在spring中,有两种动态代理模式,一种是JDK中的动态代理,另一种就是CGLib代理。
1. 什么是CGLib?
CGLib(Code Generation Library)是一个开源项目。是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类接口。Hibernate支持它来实现PO(Persistent Object 持久化对象)字节码的动态生成。Hibernate生成持久化类的javassist。
CGLib生成代理机制:采用非常底层字节码技术,生成了一个真实对象的子类,解决无接口代理问题。
2. CGLib的jar包
现在用CGLib的开发,可以不用直接导入CGLib的jar包,因为在spring的基本包的核心包spring-core-3.2.0.RELEASE.jar中已经集成了CGLib的jar包。
3. CGlib生成动态代理实例
Product类代码(真实对象):
public class ProductDao {
public void add() {
System.out.println("添加商品。。。。。。。");
}
public void update() {
System.out.println("修改商品。。。。。。。");
}
}
CGLib生成代理代码(代理对象):
//使用CGLib生成代理对象。
public class CGLibProxy implements MethodInterceptor{
private ProductDao productDao;
public CGLibProxy(ProductDao productDao) {
super();
this.productDao = productDao;
}
public ProductDao createProxy(){
//使用CGLib生成代理。
//1.创建核心类。
Enhancer enhancer = new Enhancer();
//2.为其设置父类。
enhancer.setSuperclass(productDao.getClass());
//3.设置回调。
enhancer.setCallback(this);
//4.创建代理。
return (ProductDao) enhancer.create();
}
/**
* @param proxy CGlib根据指定父类生成的代理对象
* @param method 拦截的方法
* @param args 拦截方法的参数数组
* @param methodProxy 方法的代理对象,用于执行父类的方法
*/
public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
if("add".equals(method.getName())){
System.out.println("日志记录==========================");
Object obj = methodProxy.invokeSuper(proxy, args);
return obj;
}
return methodProxy.invokeSuper(proxy, args);
}
}
测试代码(调用代理):
public void demo(){
ProductDao productDao = new ProductDao();
ProductDao proxy = new CGLibProxy(productDao).createProxy();
proxy.add();
proxy.update();
}
运行结果:
日志记录==========================
添加商品。。。。。。。
修改商品。。。。。。。