CGLIB (Code Generation Library )是一个第三方代码生成类库,运行时在内存中动态生成一个子类对象从而实现对目标对象功能的扩展。在使用CGLIB动态代理时,不要求目标对象实现接口,因此保证了目标对象不被侵入。CGLIB是采用字节码的形式实现动态代理,JDK采用反射机制调用委托类的方法实现动态代理,CGLIB采用类似索引的方式直接调用委托类方法实现动态代理。
CGLIB是针对类来实现代理的,原理是对指定的业务类生成一个子类,并覆盖其中业务方法实现代理。因为采用的是继承,所以不能对final修饰的类进行代理。
使用CGLIB动态代理,原始对象就不需要实现任何接口了,具体业务代码如下所示。
package com.obj.dao.impl;
public class UserDao {
public void add() {
System.out.println("添加用户测试");//业务代码
}
public void delete() {
System.out.println("删除用户测试");//业务代码
}
public void update() {
System.out.println("修改用户测试");//业务代码
}
public void load() {
System.out.println("查询用户测试");//业务代码
}
}
通过CGLIB实现动态代理,需要第三方jar包的支持,可以通过“https://repo1.maven.org/maven2/cglib/cglib/3.2.5/cglib-3.2.5.jar”链接来下载第三方jar包。如果有spring-core.jar包,就不如要导入第三方jar包了,因为Spring包含了CGLIB。
使用CGLIB创建代理类,要求代理类必须实现org.springframework.cglib.proxy.MethodInterceptor接口,具体操作代码如下所示。
package com.obj.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class LoggerProxy implements MethodInterceptor {
//创建代理对象
private Object target;
public Object getProxy(Object obj) {
this.target = obj;
//创建工具对象
Enhancer enhancer = new Enhancer();
//为代理类指定业务类(父类)
enhancer.setSuperclass(target.getClass());
//设置回调:对于代理类上所有方法的调用,都会调用CallBack,而Callback则需要实现intercept()方法进行拦
enhancer.setCallback(this);
//获取代理对象
Object proxy = enhancer.create();
return proxy;
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("-->开始执行 " + method.getName() + " 操作");
Object result = method.invoke(target, args);//调用业务类方法,(父类的方法)
System.out.println("-->执行结束 " + method.getName() + " 操作");
return result;
}
}
其中的操作代码与JDK动态代理基本类似,创建测试类,具体代码如下。
package com.obj.test;
import org.junit.Test;
import com.obj.dao.impl.UserDao;
import com.obj.proxy.LoggerProxy;
public class TestProxy {
@Test
public void testLogger() {
//创建代理类对象
LoggerProxy proxy = new LoggerProxy();
//创建原始对象
UserDao userDao = new UserDao();
//获取代理对象
UserDao userDaoProxy = (UserDao) proxy.getProxy(userDao);
userDaoProxy.add();
}
}
运行测试代码,同样可以实现对原始对象的代理功能。CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。CGLIB被许多AOP的框架使用,例如Spring AOP。
23万+

被折叠的 条评论
为什么被折叠?



