import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
//直接使用代理类的父类作为目标业务对象。
public class BusinessCglibProxy1 implements MethodInterceptor {
private static BusinessCglibProxy1 interceptor = new BusinessCglibProxy1();
private BusinessCglibProxy1() {}
//创建代理对象
public static Object getCglibProxy(Class<?> clazz) {
//创建一个织入器
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(clazz);
//设置需要织入的逻辑
enhancer.setCallback(interceptor);
// 创建代理对象 //使用织入器创建子类
return enhancer.create();
}
//由于CGLIB可以不需要实现接口来实现动态代理,其原理是通过字节码生成类的一个子类来完成的,
//那就有可能出现需要动态代理对象不存在一个无参构造函数,那么CGLIB在生成子类并实例化时将会产生错误。
//创建带参数的代理对象
public static Object getCglibProxy(Class<?> clazz, Class<?>[] argClazz, Object[] args) {
//创建一个织入器
Enhancer enhancer = new Enhancer();
//设置父类
enhancer.setSuperclass(clazz);
// 设置需要织入的逻辑
enhancer.setCallback(interceptor);
// 创建带参数的代理对象 //使用织入器创建子类
return enhancer.create(argClazz, args);
}
/**
* obj:cglib动态生成的代理类实例,业务类的子类的实例
* method:业务类方法的引用
* args:调用参数数组
* proxy:代理类对业务类方法的代理引用,是业务类的方法的代理
*/
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
//obj 是cglib动态生成的代理实例,是BusinessImpl的子类的实例
System.out.println("Cglib动态代理类:" + obj.getClass().getName());
System.out.println("Before " + method.getName() + " ..");
//proxy 这里是BusinessImpl的service方法Method的代理
//因为动态生成的业务类是子类或者是实现类,proxy.invokeSuper(Object obj, Object[] args)
//调用的是代理类obj的父类BusinessImpl的service方法。
//那么proxy.invoke(Object obj, Object[] args)方法是做什么的,javadoc上说这个方法
//可以用于相同类中的其他对象的方法执行,
//也就是说这个方法中的obj需要传入相同一个类的另一个对象,否则会进入无限递归循环。
//Object result = method.invoke(new BusinessImpl(), args);
Object result = proxy.invokeSuper(obj, args);
System.out.println("End "+ method.getName() + " ..");
return result;
}
public static void main(String[] args) {
BusinessImpl proxy = (BusinessImpl) BusinessCglibProxy1.getCglibProxy(BusinessImpl.class);
proxy.service();
//带参数的业务类
BusinessImpl proxy1 = (BusinessImpl) BusinessCglibProxy1.getCglibProxy(BusinessImpl.class, new Class[] {String.class}, new Object[] {"jaesonchen"});
proxy1.service();
}
}
* CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的
子类。
* CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,
性能比JDK强。
* CGLIB是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,
但因为采用的是继承,所以不能对final修饰的方法进行代理。
* CGLib采用非常底层的字节码技术,可以为一个类创建一个子类,并在子类中采用方法拦截的技术拦截
所有父类方法的调用,并顺势植入横切逻辑。
* 在我们实际开发当中,在使用动态代理进行方法请求拦截时,可能会需要判断调用的方法然后决定拦截
的逻辑,也就是同一个代理类在调用不同的方法时拦截的逻辑都不相同,CGLIB提供了CallbackFilter
来帮助我们实现这一功能。
输出为:
Cglib动态代理类:com.jaeson.BusinessImpl$$EnhancerByCGLIB$$981aa2a6
Before service ..
service.id = default
End service ..
Cglib动态代理类:com.jaeson.BusinessImpl$$EnhancerByCGLIB$$981aa2a6
Before service ..
service.id = jaesonchen
End service ..