SpringAop 代理模式
两大代理模式
实 现 AOP 的 技 术 , 主 要 分 为 两 大 类 :
静态代理:指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;
编译时编织(特殊编译器实现)和 类加载时编织(特殊的类加载器实现)
动态代理:运行时在内存中"临时"生成AOP动态代理类,因此也被称为运行时增强
JDK动态代理
1、定义动态代理处理类,实现 InvocationHandler 接口,通过构造参数接收被代理类对象实例;
2、重写 excute()方法,在方法中,通过反射执行被代理对象的方法 method.invoke();
3、method.invoke()方法需要两个参数,一个是被代理类对象引用,一个是方法参数;
4、在方法执行前可以判断切点条件,在方法执行后,可以做资源处理;
5、在生成代理对象前,需要获取被代理类的 classloader 类加载器和接口集,及动态代理类对象
实例;
6、代码:Proxy.newProxyInstance( --生成动态代理对象
obj.getClass().getClassLoader(),–获取被代理类对象的类加载器
obj.getClass.getInterfaces(), --获取被代理类对象的接口
handler --实现了 InvocationHandler 的动态代理处理器,用于生成动态代理对象
)
CGLIB动态代理
静态代理
静态代理类
自身不去完成 由代理类去完成 但是需要手动去修改方法
public static void main(String[] strParams) {
//静态代理类
//自身不去完成 由代理类去完成 但是需要手动去修改方法
UserService us = new UserServiceImpl();
TranService ts = new TranServiceImpl();
StaticProxy sp = new StaticProxy(us, ts);
sp.proxyMethod();
//理想的业务场景时 不管业务中调用哪个方法 最终 代理类都能动态进行业务代理操作
}
动态代理
动态代理类
SpringAop Aop将业务和非业务相关的代码进行分离后整合
import com.tong.service.TranService;
import com.tong.service.UserService;
public class StaticProxy {
//加入代理对象
// 代理类中需要整合的非业务代码
//SpringAop Aop将业务和非业务相关的代码进行分离后整合
//业务对象 被代理对象
private UserService userService;//通过切入点表达式找到Service
//非业务对象 增强内容
private TranService tranService;
//有参构造
public StaticProxy(UserService userService, TranService tranService) {
super();
this.userService = userService;
this.tranService = tranService;
}
public void proxyMethod() {
//代理方法的整合
try {
//事务代理
tranService.beginTran();
//业务代理
userService.save();
//业务提交
tranService.cocmmitTran();
} catch (Exception e) {
//事务回滚
tranService.rollbackTran();
}
}
}
public static void main(String[] args) {
//JDK动态代理 需要被代理对象类加载器 被代理类的接口
//被代理的类(也就是userService)必须得有接口
//被代理的类
UserService userService = new UserServiceImpl();
//创建链接
TranService tranService = new TranServiceImpl();
//动态代理
//newProxyInstance(被代理对象的类加载器, 被代理对象的接口, dp)
DynamicProxy dp = new DynamicProxy(userService, tranService);
UserService us = (UserService)
Proxy.newProxyInstance
(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(), dp);
us.update();
}