004-Spring AOP源码分析

原理分析

CGLIb

java 复制代码
OrderService orderService = new OrderService();

Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(OrderService.class);
//如果是需要所有方法都执行的setCallback
//在setCallbacks 如果设置了多个Callback 那么必须setCallbackFilter
enhancer.setCallbacks(new Callback[]{
        new MethodInterceptor() {
        	//第一个参数是代理对象 官方文档上写明了 如果invoke传入o则发生循环调用
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("执行了代理内容1");
                return methodProxy.invoke(orderService, objects);
            }
        },
        new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("执行了代理内容2");
                return methodProxy.invoke(orderService, objects);
            }
        },

});
enhancer.setCallbackFilter(new CallbackFilter() {
    @Override
    public int accept(Method method) {
        //指这个方法所执行代理intercept 的下标
        return 1;
    }
});

OrderService orderServiceProxy = (OrderService) enhancer.create();
System.out.println(orderServiceProxy.getOrderId());

动态代理

java 复制代码
BillApi phoneBill = new PhoneBillImpl();

BillApi phoneBillProxy = (BillApi) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{BillApi.class}, new InvocationHandler() {
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println("执行方法前代理");
        return method.invoke(phoneBill, objects);
    }
});

System.out.println(phoneBillProxy.getId());

Spring 统一封装

一个是继承,一个是实现,都有各自适用的场景

但是都是一个实例方法的增强

所以统一封装便于使用

java 复制代码
接口类代理
BillApi phoneBill = new PhoneBillImpl();

ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(phoneBill);
proxyFactory.addAdvice(new MethodBeforeAdvice() {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行前代理");
    }
});
proxyFactory.addAdvice(new AfterReturningAdvice() {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行后代理");
    }
});
BillApi proxy = (BillApi)proxyFactory.getProxy();
proxy.userName();
java 复制代码
非接口代理:
OrderService orderService = new OrderService();

ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(orderService);
proxyFactory.addAdvice(new MethodBeforeAdvice() {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行前代理");
    }
});
proxyFactory.addAdvice(new AfterReturningAdvice() {
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行后代理");
    }
});

OrderService proxy = (OrderService)proxyFactory.getProxy();
proxy.getOrderId();

屏蔽了底层的代理工具的切换

抽象了代理方法Advice

不需要再手动调用:被代理类(原型)的方法

相关推荐
要开心吖ZSH7 分钟前
《Spring 中上下文传递的那些事儿》Part 4:分布式链路追踪 —— Sleuth + Zipkin 实践
java·分布式·spring
桦说编程26 分钟前
深入解析CompletableFuture源码实现
java·性能优化·源码
考虑考虑27 分钟前
Springboot3.4.x中的@Bean使用
spring boot·后端·spring
努力的小雨28 分钟前
AI编程实战:云开发疯狂助攻,React + Vite 做出 FPS 网页游戏不是梦
后端
蓝澈11211 小时前
迪杰斯特拉算法之解决单源最短路径问题
java·数据结构
Kali_071 小时前
使用 Mathematical_Expression 从零开始实现数学题目的作答小游戏【可复制代码】
java·人工智能·免费
rzl021 小时前
java web5(黑马)
java·开发语言·前端
时序数据说1 小时前
为什么时序数据库IoTDB选择Java作为开发语言
java·大数据·开发语言·数据库·物联网·时序数据库·iotdb
君爱学习1 小时前
RocketMQ延迟消息是如何实现的?
后端
guojl2 小时前
深度解读jdk8 HashMap设计与源码
java