动态代理增强 Spring bean
代理模式
生成一个扩展的类代替原来的类,可以不改变原始类代码的前提下增强原始类的功能
分为静态代理和动态代理,动态代理又有两种实现方式分别是:JDK和cglib
静态代理:一个代理类只能代理一个原始类,所以每个代理类都要手动编写代理类(硬编码)
动态代理:在 JVM 运行时动态根据原始类创建代理类,避免硬编码
静态代理
// 定义接口
interface Subject {
void request();
}
// 目标类
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}
// 代理类
class ProxySubject implements Subject {
private RealSubject realSubject;
public ProxySubject() {
this.realSubject = new RealSubject();
}
@Override
public void request() {
// 增强功能:在请求前后添加日志
System.out.println("ProxySubject: Logging before request.");
realSubject.request();
System.out.println("ProxySubject: Logging after request.");
}
}
JDK 动态代理增强 Spring bean
@Component
public class Test implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
// ApplicationContextAware 回传 IOC 容器
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
// bean 后置处理器的后置处理
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof User) { // 只增强 User bean
User user = (User) applicationContext.getBean("user");
return Proxy.newProxyInstance(
user.getClass().getClassLoader(),
user.getClass().getInterfaces(), // 原始的 bean 必须要实现接口!(原始类没有实现接口时就要使用 cglib )
(Object proxy, Method method, Object[] args) -> {
if (method.getName().equals("sayHello")){ // 只增强 sayHello 方法
System.out.println("执行前.....");
Object invoke = method.invoke(user, args); // 执行目标方法(捕获异常实现环绕通知)
System.out.println("执行后.....");
return invoke;
}
return method.invoke(user, args);
}
);
}
return bean; // 如果 bean 不是 User 直接返回原来的
}
}
cglib 动态代理增强 Spring bean
@Component
public class Test implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof User) { // 只增强 User bean
User user = (User) applicationContext.getBean("user");
// 创建 CGLIB 增强器
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(user.getClass()); // 生成的代理代理类继承自是原始类(原始类不需要实现接口)
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (method.getName().equals("sayHello")) { // 只增强 sayHello 方法
System.out.println("执行前.....");
Object result = proxy.invokeSuper(obj, args); // 调用父类方法
System.out.println("执行后.....");
return result;
}
return proxy.invokeSuper(obj, args); // 其他方法直接调用
}
});
return enhancer.create(); // 创建代理实例
}
return bean; // 如果 bean 不是 User 直接返回原来的
}
}

浙公网安备 33010602011771号