CGLIB代理也叫做子类代理,在内存中构建一个子类对象而实现对目标对象的扩展
许多AOP框架使用cglib代理,在使用过程中我们需要导入的jar只要Spring Core 即可.
下面拖过一个例子来看看Cglib的使用
package com.Demo4;
public class UserDao {
public void save() {
System.out.println("开始数据库的连接.................");
}
}
其次编写一个代理类
package com.Demo4;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class ProxyFactory implements MethodInterceptor {
//目标对象
private Object target;
public ProxyFactory(Object target){
this.target = target;
}
//代理对象
public Object getProxyInstance(){
//创建工具类
Enhancer en = new Enhancer();
//设置父类
en.setSuperclass(target.getClass());
//设置回调方法
en.setCallback(this);
//创建代理对象
return en.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("...............开启事务..........");
//执行目标对象的方法
Object resultValue = method.invoke(target,objects);
System.out.println("...............结束事务..........");
return resultValue;
}
}
最后写一个测试类
package com.Demo4;
public class Test1 {
public static void main(String []args){
//得到目标对象
UserDao target = new UserDao();
//得到代理对象
UserDao proxy = (UserDao) new ProxyFactory(target).getProxyInstance();
//执行
proxy.save();
}
}
运行结果如下
从上面我们可以看出与之前不同的是我们使用Cglib代理目标对象不需要去实现接口,因此我们总结几点如下
1:如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2:目标对象实现了接口,可以强制使用CGLIB实现AOP
3:如目标对象没有实现接口,必须采用CGLIB库,spirng会自动在JDK动态代理和CGLIB之间转换
当然如果我们将目标对象的方法改为final会出现上面问题呢
package com.Demo4;
public final class UserDao {
public void save() {
System.out.println("开始数据库的连接.................");
}
}
运行下结果就知道
可以看出将目标对象的方法设置为final就会出现异常所以这说明了目标对象不可以是final
当目标对象的方法是final,static的时候不会拦截