=================================
Spring AOP动态代理之CGLib动态代理
=================================
CGLib动态代理是通过被代理类的子类产生代理对象的:
- 即使被代理类没有实现任何接口,也可以为其创建CGLib动态代理对象
CGLib依赖:
cglib
cglib
3.3.0
CGLib动态代理类:
public class CGLibProxy implements MethodInterceptor {
private Object obj; // 被代理对象
private long btime;
public CGLibProxy(Object obj) {
this.obj = obj;
}
// 产生并返回代理对象
// 代理对象是被代理对象的子类对象
// 在基类方法的覆盖版本中调用拦截器的intercept()方法
public Object getProxy() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(obj.getClass()); // 设置基类
enhancer.setCallback(this); // 设置拦截器
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method,
Object[] objects, MethodProxy methodProxy) throws Throwable {
begin(); // / obj.insert(...)
Object retval = method.invoke(obj, objects); // - obj.modify(...)
commit(); // \ obj.delete(...)
return retval;
}
private void begin() {
System.out.println("开启事务");
btime = System.nanoTime();
}
private void commit() {
System.out.println("提交事务(" +
(System.nanoTime() - btime) / 1000 + "微秒)");
}
}
测试:
public class CGLibProxyTest {
public static void main(String[] args) {
BookDao bookDao =
(BookDao)new CGLibProxy(new BookDao()).getProxy();
bookDao.insert(); // .intercept(..., insert, ...)
bookDao.modify(); // .intercept(..., modify, ...)
bookDao.delete(); // .intercept(..., delete, ...)
}
}
若抛出java.lang.reflect.InaccessibleObjectException异常:
运行
编辑配置...
修改选项
添加VM选项
--insert-opens java.base/java.lang=ALL-UNNAMED
开启事务
在t_book表中插入一条记录
提交事务(66微秒)
开启事务
修改t_book表中的一条记录
提交事务(62微秒)
开启事务
在t_book表中删除一条记录
提交事务(47微秒)
例程:SpringAOP
被代理类
___/ \____
继|承 |
v |
代理类 |
| |
v v
代理对象----->被代理对象
拦截器
CGLib动态代理是通过被代理类(如BookDao)的子类创建代理对象的:
- 即使被代理类没有实现任何接口,也能为其创建动态代理
- 被代理类必须是可被继承的类,无法为final类创建动态代理