AOP 的原理就是給目標物件建立代理物件,達到增強目標物件方法的目的
如果目標物件實現了介面就是用 JDK 動態代理,如果沒實現介面就是用三方的 CGLIB 代理
如果不使用 AOP 想要增強一個 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 工廠後置處理器,攔截所有的 bean
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 只增強 User bean
if (bean instanceof User) {
User user = (User) applicationContext.getBean("user");
return Proxy.newProxyInstance(
user.getClass().getClassLoader(),
user.getClass().getInterfaces(),
(Object proxy, Method method, Object[] args) -> {
// 如果不是 sayHello 方法不增強(只增強 sayHello 方法)
if (!method.getName().equals("sayHello")){
return method.invoke(user, args);
}
System.out.println("執行前.....");
Object invoke = method.invoke(user, args); // 執行 bean 本身的方法,這裡就是 sayHello
System.out.println("執行後.....");
return invoke;
}
);
}
// 如果 bean 不是 User 直接返回原來的
return bean;
}
}