广告
返回顶部
首页 > 资讯 > 精选 >Spring AOP核心功能源码分析
  • 539
分享到

Spring AOP核心功能源码分析

2023-07-05 07:07:24 539人浏览 泡泡鱼
摘要

这篇“spring aop核心功能源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring A

这篇“spring aop核心功能源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring AOP核心功能源码分析”文章吧。

    背景

    package com.zxc.boot.proxy;public class OrderService {    public void create() {        System.out.println("创建订单");    }    public void payOrder() {        System.out.println("支付订单");    }}

    假设你有如上的对象,需要对两个方法前面都插入生成订单号的逻辑,如果是传统的方式就可以直接加入,但是过于麻烦,如果使用spring的话,就可以借助如下的工具类,如

    ProxyFactory

    package com.zxc.boot.proxy;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.aop.framework.ProxyFactory;import java.lang.reflect.Method;public class Main {    public static void main(String[] args) {        //被代理对象        OrderService orderService = new OrderService();        ProxyFactory proxyFactory = new ProxyFactory();        //设置代理对象        proxyFactory.setTarget(orderService);        //添加代理逻辑        proxyFactory.addAdvice(new MethodBeforeAdvice() {            @Override            public void before(Method method, Object[] objects, Object o) throws Throwable {                System.out.println("-----生成订单号------");            }        });        //获取代理对象        OrderService orderServiceProxy = (OrderService) proxyFactory.getProxy();        orderServiceProxy.create();        orderServiceProxy.payOrder();    }}

    生成的结果如下(注:这里没有接口,肯定是使用cglib生成的代理对象)

    Spring AOP核心功能源码分析

    是不是很简单呢,底层逻辑都是spring帮我们实现的,而MethodBeforeAdvice就是进行的代理逻辑,它的父接口是

    Advice

    这个简单理解就是对象被代理的逻辑,主要有以下的实现,如

    MethodBeforeAdvice、AfterReturningAdvice、MethodInterceptor等等见名思义

    但是这里有一个问题,我们两个方法都被进行了代理,那么是否有办法实现只代理某个方法,而某些方法不进行代理呢,答案是有的,代码如下

    package com.zxc.boot.proxy;import org.aopalliance.aop.Advice;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.aop.Pointcut;import org.springframework.aop.PointcutAdvisor;import org.springframework.aop.framework.ProxyFactory;import org.springframework.aop.support.StaticMethodMatcherPointcut;import java.lang.reflect.Method;public class Main2 {    public static void main(String[] args) {        //被代理对象        OrderService orderService = new OrderService();        ProxyFactory proxyFactory = new ProxyFactory();        //设置代理对象        proxyFactory.setTarget(orderService);        //添加代理逻辑        proxyFactory.addAdvisor(new PointcutAdvisor() {            @Override            public Pointcut getPointcut() {                //哪些方法进行代理                return new StaticMethodMatcherPointcut() {                    @Override                    public boolean matches(Method method, Class<?> aClass) {                        //方法名为create进行代理                        return method.getName().equals("create");                    }                };            }            //代理逻辑            @Override            public Advice getAdvice() {                return new MethodBeforeAdvice() {                    @Override                    public void before(Method method, Object[] objects, Object o) throws Throwable {                        System.out.println("-----创建订单-----");                    }                };            }            @Override            public boolean isPerInstance() {                return false;            }        });        //获取代理对象        OrderService orderServiceProxy = (OrderService) proxyFactory.getProxy();        orderServiceProxy.create();        orderServiceProxy.payOrder();    }}

    Spring AOP核心功能源码分析

    可以看到,只有创建订单的方法才会添加代理逻辑,而支付订单并不会加入这段逻辑,而核心的功能点就是依赖于Pointcut对象

    Pointcut

    Pointcut简单理解就是切掉,也就是用于判断要在哪些方法或者哪些类注入代理逻辑用的

    Advisor

    而Advisor简单理解就是Advice和Pointcut的组合,spring当中进行代理的逻辑也是用Advisor为维度进行处理的

    以上,就是使用ProxyFactory进行代理逻辑的spring工具类,但是很明显这样使用相对来说还是比较麻烦的,所以spring提供了简易的方式让我们使用这种逻辑,如下

    Spring提供的代理支持

    ProxyFactoryBean

    package com.zxc.boot.proxy;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.aop.framework.ProxyFactoryBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import java.lang.reflect.Method;@Configuration@ComponentScan("com.zxc.boot.proxy")public class AppConfig {    @Bean    public ProxyFactoryBean proxyFactoryBean() {        ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();        proxyFactoryBean.setTarget(new OrderService());        proxyFactoryBean.addAdvice(new MethodBeforeAdvice() {            @Override            public void before(Method method, Object[] objects, Object o) throws Throwable {                System.out.println("-------创建订单-------");            }        });        return proxyFactoryBean;    }}
    package com.zxc.boot.proxy;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class SpringApplication {    public static void main(String[] args) {        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);        OrderService orderService = applicationContext.getBean(OrderService.class);        orderService.create();        orderService.payOrder();    }}

    Spring AOP核心功能源码分析

    只要进行如上的配置,就可以识别到了,这种方式其实跟原有的差不多,只不过spring帮我们处理了最终会返回对应的代理bean回去,但是还有更简单的方式,如下

    DefaultPointcutAdvisor

    package com.zxc.boot.proxy;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.aop.support.DefaultPointcutAdvisor;import org.springframework.aop.support.NameMatchMethodPointcut;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import java.lang.reflect.Method;@Configuration@ComponentScan("com.zxc.boot.proxy")public class AppConfig2 {    @Bean    public OrderService orderService() {        return new OrderService();    }    @Bean    public DefaultPointcutAdvisor defaultPointcutAdvisor() {        //方法名称蓝机器        NameMatchMethodPointcut nameMatchMethodPointcut = new NameMatchMethodPointcut();        nameMatchMethodPointcut.addMethodName("create");        //设置拦截和代理逻辑        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();        defaultPointcutAdvisor.setPointcut(nameMatchMethodPointcut);        defaultPointcutAdvisor.setAdvice(new MethodBeforeAdvice() {            @Override            public void before(Method method, Object[] args, Object target) throws Throwable {                System.out.println("-------创建订单------");            }        });        return defaultPointcutAdvisor;    }    //核心类,一个BeanPostProccess后置处理器,用于把扫描到的Advisor进行代理    @Bean    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {        return new DefaultAdvisorAutoProxyCreator();    }}
    package com.zxc.boot.proxy;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class SpringApplication {    public static void main(String[] args) {        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig2.class);        OrderService orderService = applicationContext.getBean(OrderService.class);        orderService.create();        orderService.payOrder();    }}

    Spring AOP核心功能源码分析

    不用我们多做其他处理,就可以对ioc容器中方法有create的类进行代理,你可以再添加一个类,如下

    package com.zxc.boot.proxy;public class UserService {    public void create() {        System.out.println("用户service哦哦哦");    }}
    package com.zxc.boot.proxy;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class SpringApplication {    public static void main(String[] args) {        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig2.class);        OrderService orderService = applicationContext.getBean(OrderService.class);        orderService.create();        orderService.payOrder();        UserService userService = applicationContext.getBean(UserService.class);        userService.create();    }}

    Spring AOP核心功能源码分析

    这样的方式就方便多了

    优化处理

    其实DefaultAdvisorAutoProxyCreator只是需要导入到ioc容器中,所以配置类可以使用import进行处理,效果是一样的,如下

    package com.zxc.boot.proxy;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.aop.support.DefaultPointcutAdvisor;import org.springframework.aop.support.NameMatchMethodPointcut;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import java.lang.reflect.Method;@Configuration@ComponentScan("com.zxc.boot.proxy")@Import(DefaultAdvisorAutoProxyCreator.class)public class AppConfig2 {    @Bean    public UserService userService() {        return new UserService();    }    @Bean    public OrderService orderService() {        return new OrderSepackage com.zxc.boot.proxy;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.aop.support.DefaultPointcutAdvisor;import org.springframework.aop.support.NameMatchMethodPointcut;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Import;import java.lang.reflect.Method;@Configuration@ComponentScan("com.zxc.boot.proxy")@Import(DefaultAdvisorAutoProxyCreator.class)public class AppConfig2 {    @Bean    public UserService userService() {        return new UserService();    }    @Bean    public OrderService orderService() {        return new OrderService();    }    @Bean    public DefaultPointcutAdvisor defaultPointcutAdvisor() {        //方法名称蓝机器        NameMatchMethodPointcut nameMatchMethodPointcut = new NameMatchMethodPointcut();        nameMatchMethodPointcut.addMethodName("create");        //设置拦截和代理逻辑        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();        defaultPointcutAdvisor.setPointcut(nameMatchMethodPointcut);        defaultPointcutAdvisor.setAdvice(new MethodBeforeAdvice() {            @Override            public void before(Method method, Object[] args, Object target) throws Throwable {                System.out.println("-------创建订单------");            }        });        return defaultPointcutAdvisor;    }//    //核心类,一个BeanPostProccess后置处理器,用于把扫描到的Advisor进行代理//    @Bean//    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {//        return new DefaultAdvisorAutoProxyCreator();//    }}rvice();    }    @Bean    public DefaultPointcutAdvisor defaultPointcutAdvisor() {        //方法名称蓝机器        NameMatchMethodPointcut nameMatchMethodPointcut = new NameMatchMethodPointcut();        nameMatchMethodPointcut.addMethodName("create");        //设置拦截和代理逻辑        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();        defaultPointcutAdvisor.setPointcut(nameMatchMethodPointcut);        defaultPointcutAdvisor.setAdvice(new MethodBeforeAdvice() {            @Override            public void before(Method method, Object[] args, Object target) throws Throwable {                System.out.println("-------创建订单------");            }        });        return defaultPointcutAdvisor;    }//    //核心类,一个BeanPostProccess后置处理器,用于把扫描到的Advisor进行代理//    @Bean//    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {//        return new DefaultAdvisorAutoProxyCreator();//    }}

    如果你不导入DefaultAdvisorAutoProxyCreator对象,那么代理逻辑就不会生效,本质就是DefaultAdvisorAutoProxyCreator类就是一个BeanPostProcessor处理器,它会针对所有类进行判断然后处理。

    以上就是关于“Spring AOP核心功能源码分析”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

    --结束END--

    本文标题: Spring AOP核心功能源码分析

    本文链接: https://www.lsjlt.com/news/350243.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • Spring AOP核心功能源码分析
      这篇“Spring AOP核心功能源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Spring A...
      99+
      2023-07-05
    • Spring AOP核心功能示例代码详解
      目录前言背景ProxyFactoryAdvicePointcutAdvisorSpring提供的代理支持ProxyFactoryBeanDefaultPointcutAdvisor优...
      99+
      2023-02-28
      Spring AOP核心功能 Spring AOP核心技术
    • Druid核心源码分析DruidDataSource
      这篇“Druid核心源码分析DruidDataSource”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Druid核心源码分...
      99+
      2023-07-05
    • Spring源码剖析1:初探Spring IOC核心流程
      本文大致地介绍了IOC容器的初始化过程,只列出了比较重要的过程和代码,可以从中看出IOC容器执行的大致流程。接下来的文章会更加深入剖析Bean容器如何解析xml,注册和初始化bean,以及如何获取bean实例等详细的过程。转自:http:/...
      99+
      2023-06-02
    • Java SpringBoot核心源码的示例分析
      本篇文章给大家分享的是有关Java SpringBoot核心源码的示例分析,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。SpringBoot源码主线分析我们要分析一个...
      99+
      2023-06-22
    • JAVA核心知识之ConcurrentHashMap源码分析
      1 前言 ConcurrentHashMap是基于Hash表的Map接口实现,键与值均不允许为NULL,他是一个线程安全的Map。同时他也是一个无序的Map,不同时间进行遍历可能会得...
      99+
      2022-11-12
    • kafka核心消费逻辑源码分析
      本篇内容主要讲解“kafka核心消费逻辑源码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“kafka核心消费逻辑源码分析”吧!消费逻辑框架搭建好之后着手开发下kafka的核心消费逻辑,流式图...
      99+
      2023-07-06
    • 源码分析Vue3响应式核心之reactive
      目录一、Reactive源码1、reactive2、接着看工厂方法createReactiveObject二、baseHandlers1、baseHandlersvue3响应式核心文...
      99+
      2023-05-17
      Vue3响应式核心reactive Vue3响应式 reactive Vue3 reactive
    • 源码分析Vue3响应式核心之effect
      目录一、effect用法1、基本用法2、lazy属性为true3、options中包含onTrack二、源码分析1、effect方法的实现2、ReactiveEffect函数源码三、...
      99+
      2023-05-17
      Vue3响应式核心effect Vue3响应式effect Vue3 effect
    • java线程池核心API源码详细分析
      目录概述源码分析ExecutorExecutorServiceScheduledExecutorServiceThreadPoolExecutorScheduledThreadPoo...
      99+
      2022-11-13
    • 关于PHP核心功能的示例分析
      关于PHP核心功能的示例分析,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。PHP是我们一直都很关注的语言之一,随着PHP6的升级,它的功能也越来越强大,我们这里...
      99+
      2023-06-17
    • java编程Reference核心原理示例源码分析
      带着问题,看源码针对性会更强一点、印象会更深刻、并且效果也会更好。所以我先卖个关子,提两个问题(没准下次跳槽时就被问到)。 我们可以用ByteBuffer的allocateDirec...
      99+
      2022-11-13
    • 简易vuex4核心原理及实现源码分析
      目录前言Vuex 核心原理使用方式vuex 运行流程核心原理实现一个简易版的 vuex实现 store 的派发和注册、响应式、injectKey实现 getters、mutation...
      99+
      2023-01-12
      vuex4核心原理 vuex4 简易版
    • 详解织梦模板DEDECMS核心类TypeLink.class.php功能分析
      Dedecms 核心类TypeLink.class.php摘要笔记,学习php就是借鉴与分析,让自己的掌握的更多。 注:'//+' 表示为本人另外加上的注释 Class TypeLink { var $typeD...
      99+
      2022-06-12
      DEDECMS TypeLink.class.php
    • Spring中AOP的切点、通知和切点表达式源码分析
      这篇文章主要介绍了Spring中AOP的切点、通知和切点表达式源码分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Spring中AOP的切点、通知和切点表达式源码分析文章都会有所收获,下面我们一起来看看吧。1...
      99+
      2023-07-05
    • elasticsearch分布式及数据的功能源码分析
      从功能上说,可以分为两部分,分布式功能和数据功能。分布式功能主要是节点集群及集群附属功能如restful借口、集群性能检测功能等,数据功能主要是索引和搜索。代码上这些功能并不是完全独...
      99+
      2022-11-13
    • mybatis的executor包语句处理功能源码分析
      这篇“mybatis的executor包语句处理功能源码分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“mybatis的e...
      99+
      2023-06-29
    • php数据库的包含查询功能源码分析
      这篇文章主要介绍了php数据库的包含查询功能源码分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇php数据库的包含查询功能源码分析文章都会有所收获,下面我们一起来看看吧。在开发web应用程序的过程中,数据库查...
      99+
      2023-07-05
    • Retrofit源码分析&实践(七)【Retrofit ConvertFactory的功能实现】
      Retrofit源码分析&实践系列文章目录 Retrofit源码分析&实践(一)【从使用入手分析源码】 Retrofit源码分析&实践(二)【Retrofit 免费的api测试工具引入】 Retro...
      99+
      2023-09-02
      retrofit android java 数据转换
    • Spring Boot实现微信扫码登录功能流程分析
      目录1. 授权流程说明第一步:请求CODE第二步:通过code获取access_token第三步:通过access_token调用接口2. 授权流程代码3. 用户登录和登出4. Sp...
      99+
      2022-11-13
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作