乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      《Spring 手?jǐn)]專欄》第 13 章:行云流水,把AOP動(dòng)態(tài)代理,融入到Bean的生命周期

       小傅哥 2021-12-13

      作者:小傅哥
      博客:https://

      ?

      沉淀、分享、成長(zhǎng),讓自己和他人都能有所收獲!??

      ?

      目錄

      • 一、前言

      • 二、目標(biāo)

      • 三、方案

      • 四、實(shí)現(xiàn)

        • 1. 工程結(jié)構(gòu)

        • 2. 定義Advice攔截器鏈

        • 3. 定義 Advisor 訪問者

        • 4. 方法攔截器

        • 5. 代理工廠

        • 6. 融入Bean生命周期的自動(dòng)代理創(chuàng)建者

      • 五、測(cè)試

        • 1. 事先準(zhǔn)備

        • 2. 自定義攔截方法

        • 3. spring.xml 配置 AOP

        • 4. 單元測(cè)試

      • 六、總結(jié)

      • 七、系列推薦

      一、前言

      嘎小子,這片代碼水太深你把握不??!

      在電視劇《楚漢傳奇》中有這么一段劉邦與韓信的飲酒對(duì)話,劉邦問韓信我那個(gè)曹參讀過書見過世面能帶多少兵,韓信說能帶一萬五,又補(bǔ)充說一萬五都吃力。劉邦又一一說出樊噲、盧綰周勃,韓信笑著說不足2萬,腦子不行。這時(shí)候劉邦有點(diǎn)掛不住臉了,問:那我呢,我能帶多少兵。韓信說,你能帶十萬。劉邦一看比他們都多,啊,還行。轉(zhuǎn)頭一想就問韓信那你呢,你能帶多少兵。韓信喝多了,說啊,我,我多多益善。這時(shí)候劉邦惱了領(lǐng)導(dǎo)勁上來了,問:那我為什么能管著你,你給我說,說呀!


      這像不像你領(lǐng)導(dǎo)問你,你能寫多少代碼、搭多少框架、接多少項(xiàng)目??赡芎艽笠徊糠譀]經(jīng)歷太多的新人碼農(nóng),僅僅是能完成一些簡(jiǎn)單的功能模塊開發(fā),而沒有辦法駕馭整個(gè)項(xiàng)目的涉及到的所有工程,也不能為項(xiàng)目提煉出一些可復(fù)用的通用性組件模塊。在初級(jí)碼農(nóng)的心里,接一點(diǎn)需求還好,但沒有人帶的時(shí)候完全接一個(gè)較大型項(xiàng)目就會(huì)比較慌了,不知道這里有沒有坑,自己也把握住不。這些代碼一塊塊的帶著能寫,但是都弄到一塊,就太難了!

      在代碼開發(fā)成長(zhǎng)的這條路上,要經(jīng)歷CRUD、ERP查數(shù)據(jù)、接口包裝、功能開發(fā)、服務(wù)整合、系統(tǒng)建設(shè)等,一直到獨(dú)立帶人承擔(dān)較大型項(xiàng)目的搭建。這一過程需要你能有大量的編寫代碼經(jīng)驗(yàn)積累和復(fù)雜問題的處理手段,之后才能一段段的把看似獨(dú)立的模塊后者代碼片段組裝成一個(gè)較大型能跑起來的項(xiàng)目。就像 Spring 的開發(fā)過程一樣,我們總是不斷在添加新的功能片段,最后又把技術(shù)實(shí)現(xiàn)與Spring 容器整合,讓使用方可以更簡(jiǎn)單的運(yùn)用 Spring 提供的能力。

      二、目標(biāo)

      在上一章節(jié)我們通過基于 Proxy.newProxyInstance 代理操作中處理方法匹配和方法攔截,對(duì)匹配的對(duì)象進(jìn)行自定義的處理操作。并把這樣的技術(shù)核心內(nèi)容拆解到 Spring 中,用于實(shí)現(xiàn) AOP 部分,通過拆分后基本可以明確各個(gè)類的職責(zé),包括你的代理目標(biāo)對(duì)象屬性、攔截器屬性、方法匹配屬性,以及兩種不同的代理操作 JDK 和 CGlib 的方式。

      再有了一個(gè) AOP 核心功能的實(shí)現(xiàn)后,我們可以通過單元測(cè)試的方式進(jìn)行驗(yàn)證切面功能對(duì)方法進(jìn)行攔截,但如果這是一個(gè)面向用戶使用的功能,就不太可能讓用戶這么復(fù)雜且沒有與 Spring 結(jié)合的方式單獨(dú)使用 AOP,雖然可以滿足需求,但使用上還是過去分散。

      因此我們需要在本章節(jié)完成 AOP 核心功能與 Spring 框架的整合,最終能通過在 Spring 配置的方式完成切面的操作。

      三、方案

      其實(shí)在有了AOP的核心功能實(shí)現(xiàn)后,把這部分功能服務(wù)融入到 Spring 其實(shí)也不難,只不過要解決幾個(gè)問題,包括:怎么借著 BeanPostProcessor 把動(dòng)態(tài)代理融入到 Bean 的生命周期中,以及如何組裝各項(xiàng)切點(diǎn)、攔截、前置的功能和適配對(duì)應(yīng)的代理器。整體設(shè)計(jì)結(jié)構(gòu)如下圖:

      • 為了可以讓對(duì)象創(chuàng)建過程中,能把xml中配置的代理對(duì)象也就是切面的一些類對(duì)象實(shí)例化,就需要用到 BeanPostProcessor 提供的方法,因?yàn)檫@個(gè)類的中的方法可以分別作用與 Bean 對(duì)象執(zhí)行初始化前后修改 Bean 的對(duì)象的擴(kuò)展信息。但這里需要集合于 BeanPostProcessor 實(shí)現(xiàn)新的接口和實(shí)現(xiàn)類,這樣才能定向獲取對(duì)應(yīng)的類信息。
      • 但因?yàn)閯?chuàng)建的是代理對(duì)象不是之前流程里的普通對(duì)象,所以我們需要前置于其他對(duì)象的創(chuàng)建,所以在實(shí)際開發(fā)的過程中,需要在 AbstractAutowireCapableBeanFactory#createBean 優(yōu)先完成 Bean 對(duì)象的判斷,是否需要代理,有則直接返回代理對(duì)象。在Spring的源碼中會(huì)有 createBean 和 doCreateBean 的方法拆分
      • 這里還包括要解決方法攔截器的具體功能,提供一些 BeforeAdvice、AfterAdvice 的實(shí)現(xiàn),讓用戶可以更簡(jiǎn)化的使用切面功能。除此之外還包括需要包裝切面表達(dá)式以及攔截方法的整合,以及提供不同類型的代理方式的代理工廠,來包裝我們的切面服務(wù)。

      四、實(shí)現(xiàn)

      1. 工程結(jié)構(gòu)

      small-spring-step-12
      └── src
          ├── main
          │   └── java
          │       └── cn.bugstack.springframework
          │           ├── aop
          │           │   ├── aspectj
          │           │   │   └── AspectJExpressionPointcut.java
          │           │   │   └── AspectJExpressionPointcutAdvisor.java
          │           │   ├── framework 
          │           │   │   ├── adapter
          │           │   │   │   └── MethodBeforeAdviceInterceptor.java
          │           │   │   ├── autoproxy
          │           │   │   │   └── MethodBeforeAdviceInterceptor.java
          │           │   │   ├── AopProxy.java
          │           │   │   ├── Cglib2AopProxy.java
          │           │   │   ├── JdkDynamicAopProxy.java
          │           │   │   ├── ProxyFactory.java
          │           │   │   └── ReflectiveMethodInvocation.java
          │           │   ├── AdvisedSupport.java
          │           │   ├── Advisor.java
          │           │   ├── BeforeAdvice.java
          │           │   ├── ClassFilter.java
          │           │   ├── MethodBeforeAdvice.java
          │           │   ├── MethodMatcher.java
          │           │   ├── Pointcut.java
          │           │   ├── PointcutAdvisor.java
          │           │   └── TargetSource.java
          │           ├── beans
          │           │   ├── factory
          │           │   │   ├── config
          │           │   │   │   ├── AutowireCapableBeanFactory.java
          │           │   │   │   ├── BeanDefinition.java
          │           │   │   │   ├── BeanFactoryPostProcessor.java
          │           │   │   │   ├── BeanPostProcessor.java
          │           │   │   │   ├── BeanReference.java
          │           │   │   │   ├── ConfigurableBeanFactory.java
          │           │   │   │   ├── InstantiationAwareBeanPostProcessor.java
          │           │   │   │   └── SingletonBeanRegistry.java
          │           │   │   ├── support
          │           │   │   │   ├── AbstractAutowireCapableBeanFactory.java
          │           │   │   │   ├── AbstractBeanDefinitionReader.java
          │           │   │   │   ├── AbstractBeanFactory.java
          │           │   │   │   ├── BeanDefinitionReader.java
          │           │   │   │   ├── BeanDefinitionRegistry.java
          │           │   │   │   ├── CglibSubclassingInstantiationStrategy.java
          │           │   │   │   ├── DefaultListableBeanFactory.java
          │           │   │   │   ├── DefaultSingletonBeanRegistry.java
          │           │   │   │   ├── DisposableBeanAdapter.java
          │           │   │   │   ├── FactoryBeanRegistrySupport.java
          │           │   │   │   ├── InstantiationStrategy.java
          │           │   │   │   └── SimpleInstantiationStrategy.java  
          │           │   │   ├── support
          │           │   │   │   └── XmlBeanDefinitionReader.java
          │           │   │   ├── Aware.java
          │           │   │   ├── BeanClassLoaderAware.java
          │           │   │   ├── BeanFactory.java
          │           │   │   ├── BeanFactoryAware.java
          │           │   │   ├── BeanNameAware.java
          │           │   │   ├── ConfigurableListableBeanFactory.java
          │           │   │   ├── DisposableBean.java
          │           │   │   ├── FactoryBean.java
          │           │   │   ├── HierarchicalBeanFactory.java
          │           │   │   ├── InitializingBean.java
          │           │   │   └── ListableBeanFactory.java
          │           │   ├── BeansException.java
          │           │   ├── PropertyValue.java
          │           │   └── PropertyValues.java 
          │           ├── context
          │           │   ├── event
          │           │   │   ├── AbstractApplicationEventMulticaster.java 
          │           │   │   ├── ApplicationContextEvent.java 
          │           │   │   ├── ApplicationEventMulticaster.java 
          │           │   │   ├── ContextClosedEvent.java 
          │           │   │   ├── ContextRefreshedEvent.java 
          │           │   │   └── SimpleApplicationEventMulticaster.java 
          │           │   ├── support
          │           │   │   ├── AbstractApplicationContext.java 
          │           │   │   ├── AbstractRefreshableApplicationContext.java 
          │           │   │   ├── AbstractXmlApplicationContext.java 
          │           │   │   ├── ApplicationContextAwareProcessor.java 
          │           │   │   └── ClassPathXmlApplicationContext.java 
          │           │   ├── ApplicationContext.java 
          │           │   ├── ApplicationContextAware.java 
          │           │   ├── ApplicationEvent.java 
          │           │   ├── ApplicationEventPublisher.java 
          │           │   ├── ApplicationListener.java 
          │           │   └── ConfigurableApplicationContext.java
          │           ├── core.io
          │           │   ├── ClassPathResource.java 
          │           │   ├── DefaultResourceLoader.java 
          │           │   ├── FileSystemResource.java 
          │           │   ├── Resource.java 
          │           │   ├── ResourceLoader.java 
          │           │   └── UrlResource.java
          │           └── utils
          │               └── ClassUtils.java
          └── test
              └── java
                  └── cn.bugstack.springframework.test
                      ├── bean
                      │   ├── IUserService.java
                      │   ├── UserService.java
                      │   └── UserServiceInterceptor.java
                      └── ApiTest.java

      工程源碼公眾號(hào)「bugstack蟲洞?!?,回復(fù):Spring 專欄,獲取完整源碼

      AOP 動(dòng)態(tài)代理融入到Bean的生命周期中類關(guān)系,如圖 13-2

      圖 13-2
      • 整個(gè)類關(guān)系圖中可以看到,在以 BeanPostProcessor 接口實(shí)現(xiàn)繼承的 InstantiationAwareBeanPostProcessor 接口后,做了一個(gè)自動(dòng)代理創(chuàng)建的類 DefaultAdvisorAutoProxyCreator,這個(gè)類的就是用于處理整個(gè) AOP 代理融入到 Bean 生命周期中的核心類。
      • DefaultAdvisorAutoProxyCreator 會(huì)依賴于攔截器、代理工廠和Pointcut與Advisor的包裝服務(wù) AspectJExpressionPointcutAdvisor,由它提供切面、攔截方法和表達(dá)式。
      • Spring 的 AOP 把 Advice 細(xì)化了 BeforeAdvice、AfterAdvice、AfterReturningAdvice、ThrowsAdvice,目前我們做的測(cè)試案例中只用到了 BeforeAdvice,這部分可以對(duì)照 Spring 的源碼進(jìn)行補(bǔ)充測(cè)試。

      2. 定義Advice攔截器鏈

      cn.bugstack.springframework.aop.BeforeAdvice

      public interface BeforeAdvice extends Advice {

      }

      cn.bugstack.springframework.aop.MethodBeforeAdvice

      public interface MethodBeforeAdvice extends BeforeAdvice {

          /**
           * Callback before a given method is invoked.
           *
           * @param method method being invoked
           * @param args   arguments to the method
           * @param target target of the method invocation. May be <code>null</code>.
           * @throws Throwable if this object wishes to abort the call.
           *                   Any exception thrown will be returned to the caller if it's
           *                   allowed by the method signature. Otherwise the exception
           *                   will be wrapped as a runtime exception.
           */

          void before(Method method, Object[] args, Object target) throws Throwable;

      }
      • 在 Spring 框架中,Advice 都是通過方法攔截器 MethodInterceptor 實(shí)現(xiàn)的。環(huán)繞 Advice 類似一個(gè)攔截器的鏈路,Before Advice、After advice等,不過暫時(shí)我們需要那么多就只定義了一個(gè) MethodBeforeAdvice 的接口定義。

      3. 定義 Advisor 訪問者

      cn.bugstack.springframework.aop.Advisor

      public interface Advisor {

          /**
           * Return the advice part of this aspect. An advice may be an
           * interceptor, a before advice, a throws advice, etc.
           * @return the advice that should apply if the pointcut matches
           * @see org.aopalliance.intercept.MethodInterceptor
           * @see BeforeAdvice
           */

          Advice getAdvice();

      }

      cn.bugstack.springframework.aop.PointcutAdvisor

      public interface PointcutAdvisor extends Advisor {

          /**
           * Get the Pointcut that drives this advisor.
           */

          Pointcut getPointcut();

      }
      • Advisor 承擔(dān)了 Pointcut 和 Advice 的組合,Pointcut 用于獲取 JoinPoint,而 Advice 決定于 JoinPoint 執(zhí)行什么操作。

      cn.bugstack.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor

      public class AspectJExpressionPointcutAdvisor implements PointcutAdvisor {

          // 切面
          private AspectJExpressionPointcut pointcut;
          // 具體的攔截方法
          private Advice advice;
          // 表達(dá)式
          private String expression;

          public void setExpression(String expression){
              this.expression = expression;
          }

          @Override
          public Pointcut getPointcut() {
              if (null == pointcut) {
                  pointcut = new AspectJExpressionPointcut(expression);
              }
              return pointcut;
          }

          @Override
          public Advice getAdvice() {
              return advice;
          }

          public void setAdvice(Advice advice){
              this.advice = advice;
          }

      }
      • AspectJExpressionPointcutAdvisor 實(shí)現(xiàn)了 PointcutAdvisor 接口,把切面 pointcut、攔截方法 advice 和具體的攔截表達(dá)式包裝在一起。這樣就可以在 xml 的配置中定義一個(gè) pointcutAdvisor 切面攔截器了。

      4. 方法攔截器

      cn.bugstack.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor

      public class MethodBeforeAdviceInterceptor implements MethodInterceptor {

          private MethodBeforeAdvice advice;

          public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
              this.advice = advice;
          }

          @Override
          public Object invoke(MethodInvocation methodInvocation) throws Throwable {
              this.advice.before(methodInvocation.getMethod(), methodInvocation.getArguments(), methodInvocation.getThis());
              return methodInvocation.proceed();
          }

      }
      • MethodBeforeAdviceInterceptor 實(shí)現(xiàn)了 MethodInterceptor 接口,在 invoke 方法中調(diào)用 advice 中的 before 方法,傳入對(duì)應(yīng)的參數(shù)信息。
      • 而這個(gè) advice.before 則是用于自己實(shí)現(xiàn) MethodBeforeAdvice 接口后做的相應(yīng)處理。其實(shí)可以看到具體的 MethodInterceptor 實(shí)現(xiàn)類,其實(shí)和我們之前做的測(cè)試是一樣的,只不過現(xiàn)在交給了 Spring 來處理

      5. 代理工廠

      cn.bugstack.springframework.aop.framework.ProxyFactory

      public class ProxyFactory {

          private AdvisedSupport advisedSupport;

          public ProxyFactory(AdvisedSupport advisedSupport) {
              this.advisedSupport = advisedSupport;
          }

          public Object getProxy() {
              return createAopProxy().getProxy();
          }

          private AopProxy createAopProxy() {
              if (advisedSupport.isProxyTargetClass()) {
                  return new Cglib2AopProxy(advisedSupport);
              }

              return new JdkDynamicAopProxy(advisedSupport);
          }

      }
      • 其實(shí)這個(gè)代理工廠主要解決的是關(guān)于 JDK 和 Cglib 兩種代理的選擇問題,有了代理工廠就可以按照不同的創(chuàng)建需求進(jìn)行控制。

      6. 融入Bean生命周期的自動(dòng)代理創(chuàng)建者

      cn.bugstack.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator

      public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPostProcessorBeanFactoryAware {

          private DefaultListableBeanFactory beanFactory;

          @Override
          public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
              this.beanFactory = (DefaultListableBeanFactory) beanFactory;
          }

          @Override
          public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

              if (isInfrastructureClass(beanClass)) return null;

              Collection<AspectJExpressionPointcutAdvisor> advisors = beanFactory.getBeansOfType(AspectJExpressionPointcutAdvisor.class).values();

              for (AspectJExpressionPointcutAdvisor advisor : advisors) {
                  ClassFilter classFilter = advisor.getPointcut().getClassFilter();
                  if (!classFilter.matches(beanClass)) continue;

                  AdvisedSupport advisedSupport = new AdvisedSupport();

                  TargetSource targetSource = null;
                  try {
                      targetSource = new TargetSource(beanClass.getDeclaredConstructor().newInstance());
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
                  advisedSupport.setTargetSource(targetSource);
                  advisedSupport.setMethodInterceptor((MethodInterceptor) advisor.getAdvice());
                  advisedSupport.setMethodMatcher(advisor.getPointcut().getMethodMatcher());
                  advisedSupport.setProxyTargetClass(false);

                  return new ProxyFactory(advisedSupport).getProxy();

              }

              return null;
          }
          
      }
      • 這個(gè) DefaultAdvisorAutoProxyCreator 類的主要核心實(shí)現(xiàn)在于 postProcessBeforeInstantiation 方法中,從通過 beanFactory.getBeansOfType 獲取 AspectJExpressionPointcutAdvisor 開始。
      • 獲取了 advisors 以后就可以遍歷相應(yīng)的 AspectJExpressionPointcutAdvisor 填充對(duì)應(yīng)的屬性信息,包括:目標(biāo)對(duì)象、攔截方法、匹配器,之后返回代理對(duì)象即可。
      • 那么現(xiàn)在調(diào)用方獲取到的這個(gè) Bean 對(duì)象就是一個(gè)已經(jīng)被切面注入的對(duì)象了,當(dāng)調(diào)用方法的時(shí)候,則會(huì)被按需攔截,處理用戶需要的信息。

      五、測(cè)試

      1. 事先準(zhǔn)備

      public class UserService implements IUserService {

          public String queryUserInfo() {
              try {
                  Thread.sleep(new Random(1).nextInt(100));
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              return "小傅哥,100001,深圳";
          }

          public String register(String userName) {
              try {
                  Thread.sleep(new Random(1).nextInt(100));
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
              return "注冊(cè)用戶:" + userName + " success!";
          }

      }
      • 在 UserService 中提供了2個(gè)不同方法,另外你還可以增加新的類來加入測(cè)試。后面我們的測(cè)試過程,會(huì)給這個(gè)兩個(gè)方法添加我們的攔截處理,打印方法執(zhí)行耗時(shí)。

      2. 自定義攔截方法

      public class UserServiceBeforeAdvice implements MethodBeforeAdvice {

          @Override
          public void before(Method method, Object[] args, Object target) throws Throwable {
              System.out.println("攔截方法:" + method.getName());
          }

      }
      • 與上一章節(jié)的攔截方法相比,我們不在是實(shí)現(xiàn) MethodInterceptor 接口,而是實(shí)現(xiàn) MethodBeforeAdvice 環(huán)繞攔截。在這個(gè)方法中我們可以獲取到方法的一些信息,如果還開發(fā)了它的 MethodAfterAdvice 則可以兩個(gè)接口一起實(shí)現(xiàn)。

      3. spring.xml 配置 AOP

      <beans>

          <bean id="userService" class="cn.bugstack.springframework.test.bean.UserService"/>

          <bean class="cn.bugstack.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

          <bean id="beforeAdvice" class="cn.bugstack.springframework.test.bean.UserServiceBeforeAdvice"/>

          <bean id="methodInterceptor" class="cn.bugstack.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor">
              <property name="advice" ref="beforeAdvice"/>
          </bean>

          <bean id="pointcutAdvisor" class="cn.bugstack.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
              <property name="expression" value="execution(* cn.bugstack.springframework.test.bean.IUserService.*(..))"/>
              <property name="advice" ref="methodInterceptor"/>
          </bean>

      </beans>
      • 這回再使用 AOP 就可以像 Spring 中一樣,通過在 xml 中配置即可。因?yàn)槲覀円呀?jīng)把 AOP 的功能融合到 Bean 的生命周期里去了,你的新增攔截方法都會(huì)被自動(dòng)處理。

      4. 單元測(cè)試

      @Test
      public void test_aop() {
          ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring.xml");
          IUserService userService = applicationContext.getBean("userService", IUserService.class);
          System.out.println("測(cè)試結(jié)果:" + userService.queryUserInfo());
      }
      • 在單元測(cè)試中你只需要按照正常獲取和使用 Bean 對(duì)象即可,不過這個(gè)時(shí)候如果被切面攔截了,那么其實(shí)你獲取到的就是對(duì)應(yīng)的代理對(duì)象里面的處理操作了。

      測(cè)試結(jié)果

      攔截方法:queryUserInfo
      測(cè)試結(jié)果:小傅哥,100001,深圳

      Process finished with exit code 0
      • 通過測(cè)試結(jié)果可以看到,我們已經(jīng)讓攔截方法生效了,也不需要自己手動(dòng)處理切面、攔截方法等內(nèi)容。截圖上可以看到,這個(gè)時(shí)候的 IUserService 就是一個(gè)代理對(duì)象

      六、總結(jié)

      • 本章節(jié)實(shí)現(xiàn) AOP 功能的外在體現(xiàn)主要是把以前自己在單元測(cè)試中的切面攔截,交給 Spring 的 xml 配置了,也就不需要自己手動(dòng)處理了。那么這里有一個(gè)非常重要的知識(shí)點(diǎn),就是把相應(yīng)的功能如何與 Spring 的 Bean 生命周期結(jié)合起來,本章節(jié)用到的 BeanPostProcessor,因?yàn)樗梢越鉀Q在 Bean 對(duì)象執(zhí)行初始化方法之前,用于修改新實(shí)例化 Bean 對(duì)象的擴(kuò)展點(diǎn),所以我們也就可以處理自己的 AOP 代理對(duì)象邏輯了。
      • 一個(gè)功能的實(shí)現(xiàn)往往包括核心部分、組裝部分、鏈接部分,為了這些各自職責(zé)的分工,則需要?jiǎng)?chuàng)建接口和類,由不同關(guān)系的繼承、實(shí)現(xiàn)進(jìn)行組裝。只有明確了各個(gè)職責(zé)分工,才好靈活的擴(kuò)展相應(yīng)的功能邏輯,否則很難駕馭大型系統(tǒng)的開發(fā)和建設(shè),也就是那種不好把握的感覺。
      • 目前我們實(shí)現(xiàn)的 AOP 與 Spring 源碼中的核心邏輯是類似的,但更會(huì)偏簡(jiǎn)單一些,也不會(huì)考慮更多的復(fù)雜場(chǎng)景遇到的問題,包括是否有構(gòu)造函數(shù)、是否為代理中的切面等。其實(shí)也可以看出只要是 Java 中的一些特性,都需要在真實(shí)使用的 Spring 中進(jìn)行完整的實(shí)現(xiàn),否則在使用這些功能的時(shí)候就會(huì)遇到各種問題。

      七、系列推薦

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多