欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring從@Aspect到Advisor使用演示實例

 更新時間:2023年02月08日 08:39:18   作者:tanglin_030907031026  
這篇文章主要介紹了Spring從@Aspect到Advisor使用演示實例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧

演示1 - 代理創(chuàng)建器

public class A17 {
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("aspect1", Aspect1.class);
        context.registerBean("config", Config.class);
        context.registerBean(ConfigurationClassPostProcessor.class);
        context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
        // BeanPostProcessor
        // 創(chuàng)建 -> (*) 依賴注入 -> 初始化 (*)
        context.refresh();
//        for (String name : context.getBeanDefinitionNames()) {
//            System.out.println(name);
//        }
        /*
            第一個重要方法 findEligibleAdvisors 找到有【資格】的 Advisors
                a. 有【資格】的 Advisor 一部分是低級的, 可以由自己編寫, 如下例中的 advisor3
                b. 有【資格】的 Advisor 另一部分是高級的, 由本章的主角解析 @Aspect 后獲得
         */
        AnnotationAwareAspectJAutoProxyCreator creator = context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
        List<Advisor> advisors = creator.findEligibleAdvisors(Target2.class, "target2");
        /*for (Advisor advisor : advisors) {
            System.out.println(advisor);
        }*/
        /*
            第二個重要方法 wrapIfNecessary
                a. 它內(nèi)部調(diào)用 findEligibleAdvisors, 只要返回集合不空, 則表示需要創(chuàng)建代理
         */
        Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1");
        System.out.println(o1.getClass());
        Object o2 = creator.wrapIfNecessary(new Target2(), "target2", "target2");
        System.out.println(o2.getClass());
        ((Target1) o1).foo();
        /*
            學(xué)到了什么
                a. 自動代理后處理器 AnnotationAwareAspectJAutoProxyCreator 會幫我們創(chuàng)建代理
                b. 通常代理創(chuàng)建的活在原始對象初始化后執(zhí)行, 但碰到循環(huán)依賴會提前至依賴注入之前執(zhí)行
                c. 高級的 @Aspect 切面會轉(zhuǎn)換為低級的 Advisor 切面, 理解原理, 大道至簡
         */
    }
    static class Target1 {
        public void foo() {
            System.out.println("target1 foo");
        }
    }
    static class Target2 {
        public void bar() {
            System.out.println("target2 bar");
        }
    }
    @Aspect // 高級切面類
    @Order(1)
    static class Aspect1 {
        @Before("execution(* foo())")
        public void before1() {
            System.out.println("aspect1 before1...");
        }
        @Before("execution(* foo())")
        public void before2() {
            System.out.println("aspect1 before2...");
        }
    }
    @Configuration
    static class Config {
        /*@Bean // 低級切面
        public Advisor advisor3(MethodInterceptor advice3) {
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression("execution(* foo())");
            DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice3);
            return advisor;
        }
        @Bean
        public MethodInterceptor advice3() {
            return invocation -> {
                System.out.println("advice3 before...");
                Object result = invocation.proceed();
                System.out.println("advice3 after...");
                return result;
            };
        }*/
    }
}

收獲??

AnnotationAwareAspectJAutoProxyCreator 的作用

  • 將高級 @Aspect 切面統(tǒng)一為低級 Advisor 切面
  • 在合適的時機創(chuàng)建代理

findEligibleAdvisors 找到有【資格】的 Advisors

  • 有【資格】的 Advisor 一部分是低級的, 可以由自己編寫, 如本例 A17 中的 advisor3
  • 有【資格】的 Advisor 另一部分是高級的, 由解析 @Aspect 后獲得

wrapIfNecessary

  • 它內(nèi)部調(diào)用 findEligibleAdvisors, 只要返回集合不空, 則表示需要創(chuàng)建代理
  • 它的調(diào)用時機通常在原始對象初始化后執(zhí)行, 但碰到循環(huán)依賴會提前至依賴注入之前執(zhí)行

演示2 - 代理創(chuàng)建時機

public class A17_1 {
    public static void main(String[] args) {
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean(ConfigurationClassPostProcessor.class);
        context.registerBean(Config.class);
        context.refresh();
        context.close();
        // 創(chuàng)建 -> (*) 依賴注入 -> 初始化 (*)
        /*
            學(xué)到了什么
                a. 代理的創(chuàng)建時機
                    1. 初始化之后 (無循環(huán)依賴時)
                    2. 實例創(chuàng)建后, 依賴注入前 (有循環(huán)依賴時), 并暫存于二級緩存
                b. 依賴注入與初始化不應(yīng)該被增強, 仍應(yīng)被施加于原始對象
         */
    }
    @Configuration
    static class Config {
        @Bean // 解析 @Aspect、產(chǎn)生代理
        public AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator() {
            return new AnnotationAwareAspectJAutoProxyCreator();
        }
        @Bean // 解析 @Autowired
        public AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor() {
            return new AutowiredAnnotationBeanPostProcessor();
        }
        @Bean // 解析 @PostConstruct
        public CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor() {
            return new CommonAnnotationBeanPostProcessor();
        }
        @Bean
        public Advisor advisor(MethodInterceptor advice) {
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression("execution(* foo())");
            return new DefaultPointcutAdvisor(pointcut, advice);
        }
        @Bean
        public MethodInterceptor advice() {
            return (MethodInvocation invocation) -> {
                System.out.println("before...");
                return invocation.proceed();
            };
        }
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }
        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }
    }
    static class Bean1 {
        public void foo() {
        }
        public Bean1() {
            System.out.println("Bean1()");
        }
        @Autowired public void setBean2(Bean2 bean2) {
            System.out.println("Bean1 setBean2(bean2) class is: " + bean2.getClass());
        }
        @PostConstruct public void init() {
            System.out.println("Bean1 init()");
        }
    }
    static class Bean2 {
        public Bean2() {
            System.out.println("Bean2()");
        }
        @Autowired public void setBean1(Bean1 bean1) {
            System.out.println("Bean2 setBean1(bean1) class is: " + bean1.getClass());
        }
        @PostConstruct public void init() {
            System.out.println("Bean2 init()");
        }
    }
}

收獲??

代理的創(chuàng)建時機

  • 初始化之后 (無循環(huán)依賴時)
  • 實例創(chuàng)建后, 依賴注入前 (有循環(huán)依賴時), 并暫存于二級緩存

依賴注入與初始化不應(yīng)該被增強, 仍應(yīng)被施加于原始對象

演示3 - @Before 對應(yīng)的低級通知

public class A17_2 {
    static class Aspect {
        @Before("execution(* foo())")
        public void before1() {
            System.out.println("before1");
        }
        @Before("execution(* foo())")
        public void before2() {
            System.out.println("before2");
        }
        public void after() {
            System.out.println("after");
        }
        public void afterReturning() {
            System.out.println("afterReturning");
        }
        public void afterThrowing() {
            System.out.println("afterThrowing");
        }
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            try {
                System.out.println("around...before");
                return pjp.proceed();
            } finally {
                System.out.println("around...after");
            }
        }
    }
    static class Target {
        public void foo() {
            System.out.println("target foo");
        }
    }
    @SuppressWarnings("all")
    public static void main(String[] args) throws Throwable {
        AspectInstanceFactory factory = new SingletonAspectInstanceFactory(new Aspect());
        // 高級切面轉(zhuǎn)低級切面類
        List<Advisor> list = new ArrayList<>();
        for (Method method : Aspect.class.getDeclaredMethods()) {
            if (method.isAnnotationPresent(Before.class)) {
                // 解析切點
                String expression = method.getAnnotation(Before.class).value();
                AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
                pointcut.setExpression(expression);
                // 通知類
                AspectJMethodBeforeAdvice advice = new AspectJMethodBeforeAdvice(method, pointcut, factory);
                // 切面
                Advisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
                list.add(advisor);
            }
        }
        for (Advisor advisor : list) {
            System.out.println(advisor);
        }
        /*
            @Before 前置通知會被轉(zhuǎn)換為下面原始的 AspectJMethodBeforeAdvice 形式, 該對象包含了如下信息
                a. 通知代碼從哪兒來
                b. 切點是什么(這里為啥要切點, 后面解釋)
                c. 通知對象如何創(chuàng)建, 本例共用同一個 Aspect 對象
            類似的通知還有
                1. AspectJAroundAdvice (環(huán)繞通知)
                2. AspectJAfterReturningAdvice
                3. AspectJAfterThrowingAdvice
                4. AspectJAfterAdvice (環(huán)繞通知)
         */
    }
}

收獲??

@Before 前置通知會被轉(zhuǎn)換為原始的 AspectJMethodBeforeAdvice 形式, 該對象包含了如下信息

  • 通知代碼從哪兒來
  • 切點是什么(這里為啥要切點, 后面解釋)
  • 通知對象如何創(chuàng)建, 本例共用同一個 Aspect 對象

類似的還有

  • AspectJAroundAdvice (環(huán)繞通知)
  • AspectJAfterReturningAdvice
  • AspectJAfterThrowingAdvice (環(huán)繞通知)
  • AspectJAfterAdvice (環(huán)繞通知)

到此這篇關(guān)于Spring從@Aspect到Advisor使用演示實例的文章就介紹到這了,更多相關(guān)Spring @Aspect Advisor內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 聊聊如何在springboot中添加模版

    聊聊如何在springboot中添加模版

    本文,我們談?wù)勅绾卧?nbsp;spring boot 中添加模版,因為有時候我們也是需要后端渲染的嘛,比如公司官網(wǎng),文中有詳細的代碼示例供我們參考,需要的朋友可以參考下
    2023-08-08
  • mapper.xml無法解析字段的問題

    mapper.xml無法解析字段的問題

    這篇文章主要介紹了mapper.xml無法解析字段的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java實現(xiàn)文件的分割與合并

    Java實現(xiàn)文件的分割與合并

    這篇文章主要為大家詳細介紹了Java實現(xiàn)文件的分割與合并,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 詳解Java的Struts框架以及相關(guān)的MVC設(shè)計理念

    詳解Java的Struts框架以及相關(guān)的MVC設(shè)計理念

    這篇文章主要介紹了詳解Java的Struts框架以及相關(guān)的MVC設(shè)計理念,Struts是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-12-12
  • maven項目不編譯xml文件問題

    maven項目不編譯xml文件問題

    這篇文章主要介紹了maven項目不編譯xml文件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-09-09
  • Java的Synchronized關(guān)鍵字學(xué)習(xí)指南(全面 & 詳細)

    Java的Synchronized關(guān)鍵字學(xué)習(xí)指南(全面 & 詳細)

    這篇文章主要給大家介紹了關(guān)于Java的Synchronized關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java實現(xiàn)ModbusTCP通信功能

    Java實現(xiàn)ModbusTCP通信功能

    使用ModbusTCP實現(xiàn)和硬件設(shè)備通信功能,本文通過實例圖文相結(jié)合給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • springboot項目組引入JMeter的實現(xiàn)步驟

    springboot項目組引入JMeter的實現(xiàn)步驟

    本文主要介紹了springboot項目組引入JMeter的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • java書店系統(tǒng)畢業(yè)設(shè)計 用戶模塊(2)

    java書店系統(tǒng)畢業(yè)設(shè)計 用戶模塊(2)

    這篇文章主要介紹了java書店系統(tǒng)畢業(yè)設(shè)計,第二步系統(tǒng)總體設(shè)計,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java設(shè)計模式之享元模式示例詳解

    Java設(shè)計模式之享元模式示例詳解

    享元模式(FlyWeight?Pattern),也叫蠅量模式,運用共享技術(shù),有效的支持大量細粒度的對象,享元模式就是池技術(shù)的重要實現(xiàn)方式。本文將通過示例詳細講解享元模式,感興趣的可以了解一下
    2022-03-03

最新評論