JDK与CGLIB动态代理区别:
JDK动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
CGLIB动态代理是利用asm开源包,将代理对象类的class进来,通过修改其字节码文件生成子类来处理。
对于动态代理来说,Spring框架中的AOP使用最为经典:
- 如果目标对象实现了接口,默认情况下采用JDK的动态代理实现AOP
- 如果目标对象实现了接口,可以强制使用CGLIB实现AOP。只要在Spring配置文件中添加 <aop:aspectj-autoproxy proxy-target-class=“true”/>
- 如果目标对象没有实现接口,必须采用CGLIB方式,Spring会自动在JDK动态代理和CGLIB动态代理之间转换
注意事项:
- JDK动态代理只能对实现了接口的类生成代理
- CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,被代理类不要求实现接口。因为采用的继承的方式,所以被代理类中的方法不能用final修饰。
JDK动态代理实现示例:
创建被代理服务器类
public interface JDKService {
void doService();
}
public class JDKServiceImpl implements JDKService {
@Override
public void doService() {
System.out.println("do service...");
}
}
创建代理类,并调用被代理服务类中的方法:
public class JDKProxy {
/**
* 创建代理对象
*
* @param target 被代理对象
* @return 代理对象
*/
public static Object newJDKProxy(final Object target) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), // 代理接口
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK动态代理,监听开始!");
Object result = method.invoke(target, args); // 方法调用
System.out.println("JDK动态代理,监听结束!");
return result;
}
});
}
public static void main(String[] args) {
JDKService jdkService = new JDKServiceImpl();
JDKService service = (JDKService) newJDKProxy(jdkService);
service.doService();
}
}
CGLIB动态代理实现示例:
创建被代理服务类:
public class CGLIBService {
public void doService() {
System.out.println("doService...");
}
}
创建代理类,并调用被代理服务类中的方法:
public class CGLIBProxy {
/**
* 创建代理对象
*
* @param target 被代理对象
* @return 代理对象
*/
public Object newCGLIBProxy(final Object target) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass()); // 设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类
enhancer.setCallback(new MethodInterceptor() { // 设置回调
@Override
public Object intercept(Object o, Method method, Object[] parameters, MethodProxy methodProxy) throws Throwable {
System.out.println("Cglib动态代理,监听开始!");
Object result = method.invoke(target, parameters); // 方法执行
System.out.println("Cglib动态代理,监听结束!");
return result;
}
});
Object result = enhancer.create(); // 创建并返回代理对象
return result;
}
public static void main(String[] args) {
CGLIBProxy cglib = new CGLIBProxy(); // 实例化CglibProxy对象
CGLIBService service = (CGLIBService) cglib.newCGLIBProxy(new CGLIBService()); // 获取代理对象
service.doService();
}
}