上面我们使用注解配置,注解配置使用很方便也很快速,但它不够灵活,不好维护。下面我们将使用配置文件来建立AOP。
我们还是基于上面的例子,使用配置文件,我们只需修改上面的SecurityHandler.java和applicationContext.xml,代码如下:
SecurityHandler.java
public class SecurityHandler { private void checkSecurity() { System.out.println("------checkSecurity()------"); }
} |
applicationContext.xml
<bean id="securityHandler"class="spring.SecurityHandler"/>
<bean id="userManager" class="spring.UserManagerImpl"/>
<aop:config> <aop:aspect id="security" ref="securityHandler"> <aop:pointcut id="allAddMethod" expression="execution(*spring.UserManagerImpl.add*(..))" /> <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/> </aop:aspect> </aop:config> |
从上面代码,我们会发现一个问题,如何在切面中如何传递参数呢?
我们切面的参数都封装在JoinPoint类中,得到参数使用joinPoint.getArgs()返回一个数组,得到方法名使用joinPoint.getSignature().getName()。
测试一下,修改SecurityHandler.java
public class SecurityHandler {
private void checkSecurity(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); for (int i=0; i<args.length; i++) { System.out.println(args[i]); } System.out.println(joinPoint.getSignature().getName()); System.out.println("----checkSecurity()----"); }
} |
spring对AOP的支持
1、如果目标对象实现了接口,在默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,也可以强制使用CGLIB生成代理实现AOP
3、如果目标对象没有实现接口,那么必须引入CGLIB,spring会在JDK的动态代理和CGLIB代理之间切换
如何强制使用CGLIB生成代码?
* 加入CGLIB库,SPRING_HOME/lib/cglib/*.jar
* 加入如下配置,强制使用CGLIB代理
<aop:aspectj-autoproxy proxy-target-class="true"/>
JDK动态代理和CGLIB代理的区别?
* JDK动态代理对实现了接口的类进行代理
* CGLIB代理可以对类代理,主要对指定的类生成一个子类,因为是继承
我们的目标最好不要使用final声明