说明
CGLIB 是通过操作字节码生成现实类
的子类,将子类中的现实方法转发到拦截器中,拦截器再调用现实类
的方法
Code demo
现实类
public class UserQueryImpl {
public Integer update() {
log.info("更新用户操作");
return null;
}
public String queryUserName() {
log.info("查询用户操作");
return null;
}
}
拦截器
public class LogInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
before(o, method, args);
Object result = methodProxy.invokeSuper(o, args);
after(o, method, args);
return result;
}
public void before(Object actualClass, Method method, Object[] args) {
log.info("before run :class={} method={} args={}", actualClass.getClass(), method.getName(), args);
}
public void after(Object actualClass, Method method, Object[] args) {
log.info("after run :class={} method={} args={}", actualClass.getClass(), method.getName(), args);
}
}
创建代理
public class CglibProxy {
public static <T> T make(T object) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(object.getClass());
enhancer.setCallback(new LogInterceptor());
return (T) enhancer.create();
}
}
调用
public void testCglib() {
UserQueryImpl userQuery = CglibProxy.make(new UserQueryImpl());
userQuery.queryUserName();
userQuery.update();
}
总结
- CGLIB 与 JDK 动态代理的区别
- JDK 是通过反射实现,CGLIB 是通过生成字节码实现
- JDK 动态代理需要
现实类
有接口实现,CGLIB 不需要
- 实际开发中的作用:
- 在实际开发中,
拦截器
或者调用类
往往都是实现一些公用的、全局性的逻辑,普通开发只用聚焦业务开发,就整体项目而言,动态代理极大地减少了项目的耦合性。