中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring?AOP核心功能源碼分析

發布時間:2023-02-28 10:57:45 來源:億速云 閱讀:93 作者:iii 欄目:開發技術

這篇“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核心功能源碼分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    星子县| 榆树市| 紫金县| 舒城县| 潼关县| 德昌县| 诏安县| 彩票| 正阳县| 江达县| 眉山市| 新绛县| 莫力| 宁波市| 布拖县| 油尖旺区| 惠安县| 海南省| 景东| 广德县| 泰和县| 威信县| 蓝山县| 东明县| 密山市| 南陵县| 社会| 梧州市| 厦门市| 庆阳市| 奇台县| 襄城县| 安康市| 明溪县| 惠州市| 秦皇岛市| 宁城县| 漯河市| 玉树县| 兴和县| 林口县|