在各个方法处的公共代码提取到一处,并通过类似******的机制实现代码的动态织入。可以简单地想象成,在某个方法的调用前、返回前、调用后和抛出异常时,动态插入自己的代码。在弄清楚Pointcut、Advice之类的术语前,不如编写一个最简单的AOP应用来体验一下。
考虑一下通常的Web应用程序都会有日志记录,我们来编写一个LogAdvisor,对每个业务方法调用前都作一个记录:
/**
* Copyright_2006, Liao Xuefeng
* Created on 2006-3-9
*/
package com.crackj2ee.example.spring;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class LogAdvisor implements MethodBeforeAdvice {
public void before(Method m, Object[] args, Object target) throws Throwable {
System.out.println("[Log] " + target.getClass().getName() + "." + m.getName() + "()");
}
}
然后,修改beans.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="serviceTarget" class="com.crackj2ee.example.spring.MyServiceBean" />
<bean id="logAdvisor" class="com.crackj2ee.example.spring.LogAdvisor" />
<bean id="service" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces"><value>com.crackj2ee.example.spring.ServiceBean</value></property>
<property name="target"><ref local="serviceTarget"/></property>
<property name="interceptorNames">
<list>
<value>logAdvisor</value>
</list>
</property>
</bean>
</beans>
注意观察修改后的配置文件,我们使用了一个ProxyFactoryBean作为service来与客户端打交道,而真正的业务Bean即MyServiceBean被声明为serviceTarget并作为参数对象传递给ProxyFactoryBean,proxyInterfaces指定了返回的接口类型。对于客户端而言,将感觉不出任何变化,但却动态加入了LogAdvisor,关系如下:
运行结果如下,可以很容易看到调用了哪些方法:
Spring + Eclipse开发入门(5)
时间:2011-02-09
要截获指定的某些方法也是可以的。下面的例子将修改getPassword()方法的返回值:
/**
* Copyright_2006, Liao Xuefeng
* Created on 2006-3-9
* For more information, please visit:http://www.crackj2ee.com
*/
package com.crackj2ee.example.spring;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class PasswordAdvisor implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
Object ret = invocation.proceed();
if(ret==null)
return null;
String password = (String)ret;
StringBuffer encrypt = new StringBuffer(password.length());
for(int i=0; i<password.length(); i++)
encrypt.append(''*'');
retu
|