AOP
静态代理类:
原理:
真实类和代理类都实现于同一个接口,代理类包含真实类的对象
其方法中调用真实类对象的对应方法并编写其需要的增强操作。
优点:
1.业务类只需要关注业务逻辑本身,保证了业务类的重用性。
2.把真实对象隐藏起来了,保护真实对象
缺点:
1.代理对象的某个接口只服务于某一种类的对象,即每一个真实对象都需要一个代理对象
2.如果需要代理的方法很多,则要为每一种方法都进行代理处理。
3.如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。
动态代理类:
JDK动态代理
return Proxy.newProxyInstance(target.getClass().getClassLoader(),//类加载器,一般跟上真实对象的类加载器
target.getClass().getInterfaces(),//真实对象实现的接口,JDK动态代理必须要求真实对象有接口
h);
/**
*h为实现了InvaocationHandler接口,并覆盖其
*public Object invoke(Object proxy, Method method, Object[] args)throws Throwable{return null}
*的类对象,
*invoke()中写增强代码
*/
CGLIB动态代理
Enhancer enhancer = new Enhancer(); //创建代理对象
enhancer.setSuperclass(target.getClass()); //设置继承于增强对象的
enhancer.serCallback(this); //设置增强对象
return enhancer;
拦截器Interceptor
AOP:
原理:动态代理
思想:
将增强操作封装成类,在生成动态代理类时,调用需要增强操作的对应方法
开发:
包spring-aop-版本.RELEASE.jar
com.springsource.org.aopaliance-1.0.0.jar
com.springsource-org-aspectj.weaver-1.6.8.RELEASE.jar
XML:
<bean id="txManager" class="">
<aop:config proxy-target-class="false"> //proxy-target-class默认为false,使用JDK动态代理,true使用CGLIB动态代理
<aop:aspect ref="txManager" >
//指定被增强的方法,expression中AOP语法指定被增强方法
<aop:pointcut id="txPoint" expression="execution(* cn.volfcode,service.*Service.*(..))" />
<aop:before method="begin" pointcut-ref="txPoint" /> //给指定方法添加增操作和增强操作的执行时机
<aop:after-returning method="commit" pointcut-ref="txPoint" />
<aop:after-throwing method="rolback" pointcut-ref="txPoint" />
<aop:around method="aroundMethod" pointcut-ref="txPoint" /> //环绕增强
</aop:aspect>
</aop:config>
注解:
@Aspect("execution(..)")
@Pointcut
使用:
配置解析器
<aop:aspectj-autoproxy />
@Aspect
public class xxx{ //增强操作类
@Pointcut("execution(...)") //指定被增强方法
public void txPoint(){}
@Before("txPoint()") //增强操作,jp为被增强方法
public void begin(JoinPoint jp){}
@AfterThrowing(value="txPoint()",throwing="e")
public void rollback(JoinPoint jp,Throwable e){}
@Around("txPoint") //可以自行控制执行顺序,解决问题:注解的AfterThrowing和After执行顺序和XML配置的执行顺序相反
public Object aroundMethod(ProceedingJoinPoint pjp){
Object ret = null;
begin();
try{
ret=pjp.proceed();//调用真实对象的方法
}catch(Throwable e){
}finally{
}
return ret;
}
}