AOP - 自己寫 JDK 動態代理增強 bean

CyrusHuang發表於2024-10-20

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;
    }
}

相關文章