<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Spring生命周期最詳解

          共 47016字,需瀏覽 95分鐘

           ·

          2021-03-14 18:18

          點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

          優(yōu)質(zhì)文章,第一時(shí)間送達(dá)

          目的

          在大三開始學(xué)習(xí)spring時(shí),老師就說spring bean周期非常重要,當(dāng)時(shí)也有仔細(xì)看,但是說實(shí)話搞不大懂,后面工作面試也問過,還是有點(diǎn)模糊,就是沒有掌握好,進(jìn)行深入理解,這次“老大”又問到了。不允許再回避了,所以這次堅(jiān)決搞明白,理解生命周期作用,為啥要這樣設(shè)計(jì),我們能在生命周期做哪些更高層次的編程。


          生命周期流程圖

          先總體看下spring的生命周期流程圖,實(shí)現(xiàn)(繼承)這些接口(抽象類)并在容器里注冊,就可以看到bean的生命周期會(huì)按下面流程進(jìn)行,后面會(huì)給出測試代碼。



          可以看出設(shè)計(jì)策略是“先顧大局”-類似的操作BeanFactory一般出現(xiàn)在Bean之前,操作完Bean之后,BeanFactory會(huì)進(jìn)行“管理”;Bean操作的前提是應(yīng)用了BeanPostProcessor。


          測試代碼

          要被注冊的Person類

          package springBeanTest;

          import org.springframework.beans.BeansException;
          import org.springframework.beans.factory.*;

          public class Person implements BeanFactoryAware, BeanNameAware, InitializingBean, DisposableBean {
              private String name;
              private String address;
              private int phone;
              private BeanFactory beanFactory;
              private String beanName;

              public Person() {
                  System.out.println("【構(gòu)造器】調(diào)用Person的構(gòu)造器實(shí)例化");
              }

              public String getName() {
                  return name;
              }

              public void setName(String name) {
                  System.out.println("【注入屬性】name");
                  this.name = name;
              }

              public String getAddress() {
                  return address;
              }

              public void setAddress(String address) {
                  System.out.println("【注入屬性】address");
                  this.address = address;
              }

              public int getPhone() {
                  return phone;
              }

              public void setPhone(int phone) {
                  System.out.println("【注入屬性】phone");
                  this.phone = phone;
              }

              // 這是BeanFactoryAware接口方法
              public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
                  System.out.println("【BeanFactoryAware接口】調(diào)用setBeanFactory方法");
                  this.beanFactory = beanFactory;
              }

              // 這是BeanNameAware接口方法
              public void setBeanName(String s) {
                  System.out.println("【BeanNameAware接口】調(diào)用setBeanName方法");
                  this.beanName = s;
              }

              // 這是DiposibleBean接口方法
              public void destroy() throws Exception {
                  System.out.println("【DiposibleBean接口】調(diào)用destroy方法");
              }

              // 這是InitializingBean接口方法
              public void afterPropertiesSet() throws Exception {
                  System.out.println("【InitializingBean接口】調(diào)用afterPropertiesSet方法");
              }

              // 通過<bean>的init-method屬性指定的初始化方法
              public void myInit() {
                  System.out.println("【init-method】調(diào)用<bean>的init-method屬性指定的初始化方法");
              }

              // 通過<bean>的destroy-method屬性指定的初始化方法
              public void myDestory() {
                  System.out.println("【destroy-method】調(diào)用<bean>的destroy-method屬性指定的初始化方法");
              }
          }

          實(shí)現(xiàn)BeanFactoryPostProcessor的類

          package springBeanTest;

          import org.springframework.beans.BeansException;
          import org.springframework.beans.factory.config.BeanDefinition;
          import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
          import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

          public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
              public MyBeanFactoryPostProcessor() {
                  super();
                  System.out.println("這是BeanFactoryPostProcessor實(shí)現(xiàn)類構(gòu)造器??!");
              }

              public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
                  System.out
                          .println("BeanFactoryPostProcessor調(diào)用postProcessBeanFactory方法");
                  BeanDefinition bd = configurableListableBeanFactory.getBeanDefinition("person");
                  bd.getPropertyValues().addPropertyValue("phone""110");
              }
          }

          繼承InstantiationAwareBeanPostProcessorAdapter的類

          package springBeanTest;

          import java.beans.PropertyDescriptor;

          import org.springframework.beans.BeansException;
          import org.springframework.beans.PropertyValues;
          import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;

          public class MyInstantiationAwareBeanPostProcessor extends
                  InstantiationAwareBeanPostProcessorAdapter {

              public MyInstantiationAwareBeanPostProcessor() {
                  super();
                  System.out
                          .println("這是InstantiationAwareBeanPostProcessorAdapter實(shí)現(xiàn)類構(gòu)造器??!");
              }

              // 接口方法、實(shí)例化Bean之前調(diào)用
              @Override
              public Object postProcessBeforeInstantiation(Class beanClass,
                                                           String beanName) throws BeansException {
                  System.out
                          .println("InstantiationAwareBeanPostProcessor調(diào)用postProcessBeforeInstantiation方法");
                  return null;
              }

              // 接口方法、實(shí)例化Bean之后調(diào)用
              @Override
              public Object postProcessAfterInitialization(Object bean, String beanName)
                      throws BeansException {
                  System.out
                          .println("InstantiationAwareBeanPostProcessor調(diào)用postProcessAfterInitialization方法");
                  return bean;
              }

              // 接口方法、設(shè)置某個(gè)屬性時(shí)調(diào)用
              @Override
              public PropertyValues postProcessPropertyValues(PropertyValues pvs,
                                                              PropertyDescriptor[] pds, Object bean, String beanName)
                      throws BeansException {
                  System.out
                          .println("InstantiationAwareBeanPostProcessor調(diào)用postProcessPropertyValues方法");
                  return pvs;
              }
          }

          實(shí)現(xiàn)BeanPostProcessor的類

          package springBeanTest;

          import org.springframework.beans.BeansException;
          import org.springframework.beans.factory.config.BeanPostProcessor;

          public class MyBeanPostProcessor implements BeanPostProcessor{
              public MyBeanPostProcessor(){
                  System.out.println("這是BeanPostProcessor實(shí)現(xiàn)類構(gòu)造器?。?);
              }
              public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
                  System.out.println("BeanPostProcessor接口方法postProcessBeforeInitialization對屬性進(jìn)行更改");
                  return o;
              }

              public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
                  System.out.println("BeanPostProcessor接口方法postProcessAfterInitialization對屬性進(jìn)行更改");
                  return o;
              }
          }

          測試類BeanLifeCycle

          package springBeanTest;

                  import org.springframework.context.ApplicationContext;
                  import org.springframework.context.support.ClassPathXmlApplicationContext;

          public class BeanLifeCycle {

              public static void main(String[] args) {

                  System.out.println("現(xiàn)在開始初始化容器");

                  ApplicationContext factory = new ClassPathXmlApplicationContext("beans.xml");
                  System.out.println("容器初始化成功");
                  //得到Preson,并使用
                  Person person = factory.getBean("person",Person.class);
                  System.out.println(person);

                  System.out.println("現(xiàn)在開始關(guān)閉容器!");
                  ((ClassPathXmlApplicationContext)factory).registerShutdownHook();
              }
          }

          配置文件

          <?xml version="1.0" encoding="UTF-8"?>

          <beans xmlns="http://www.springframework.org/schema/beans"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
                 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
                 xsi:schemaLocation="
                      http://www.springframework.org/schema/beans
                      http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"
          >

              <bean id="beanPostProcessor" class="springBeanTest.MyBeanPostProcessor">
              </bean>

              <bean id="instantiationAwareBeanPostProcessor" class="springBeanTest.MyInstantiationAwareBeanPostProcessor">
              </bean>

              <bean id="beanFactoryPostProcessor" class="springBeanTest.MyBeanFactoryPostProcessor">
              </bean>

              <bean id="person" class="springBeanTest.Person" init-method="myInit"
                    destroy-method="myDestory" scope="singleton" p:name="張三" p:address="廣州"
                    p:phone="123567889"/>
          </beans>


          生命周期的接口和抽象類

          大概了解了生命周期的流程和運(yùn)用到哪些接口和抽象類之后,下面開始進(jìn)一步深入了解他們的具體作用,按照流程往下一一介紹。


          這里spring版本是4.1.8.RELEASE。


          BeanFactoryPostProcessor接口

          package org.springframework.beans.factory.config;

          import org.springframework.beans.BeansException;

          public interface BeanFactoryPostProcessor {
              void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
          }

          該接口只有一個(gè)postProcessBeanFactory方法,BeanFactoryPostProcessor:在bean factory標(biāo)準(zhǔn)初始化之后可以進(jìn)行修改。將加載所有bean定義,但是還沒有實(shí)例化bean。這個(gè)方法允許重新覆蓋或者添加屬性甚至快速的初始化bean。


          初次看不知干嘛,關(guān)鍵在于參數(shù),可以利用參數(shù)做一些操作。


          下面了解一下這個(gè)參數(shù)。 

          ConfigurableListableBeanFactory 提供分析、修改bean定義和預(yù)先實(shí)例化單例。這個(gè)BeanFactory的子接口不應(yīng)該是被使用于普通應(yīng)用程序中:BeanFactory和ListableBeanFactory鐵錚錚作為最經(jīng)典的用例;這個(gè)接口是僅應(yīng)該允許內(nèi)部框架使用,即使在訪問bean factory配置方法時(shí)也如此。


          ConfigurableListableBeanFactory 的方法


          • freezeConfiguration():凍結(jié)全部bean定義,給被注冊的bean定義發(fā)信號告訴它們今后不再被修改和進(jìn)一步后續(xù)處理。它允許factory去積極緩存bean定義元數(shù)據(jù)。

          • getBeanDefinition(String beanName):根據(jù)指定的bean name返回被注冊的bean定義,允許訪問其屬性值和構(gòu)造函數(shù)參數(shù)值(可以在bean工廠后期處理期間被修改)。這個(gè)被返回的bean definition對象不應(yīng)該是副本而是原始在工廠被注冊的。這意味著如果需要它可以被轉(zhuǎn)換為更具體的實(shí)現(xiàn)類型。注意這個(gè)方法只能獲得本地工廠bean definition。

          • Iterator getBeanNamesIterator():返回由這個(gè)bean factory管理的所有bean name統(tǒng)一視圖。

          • void ignoreDependencyType(Class<?> type):忽略被給定注入依賴類型 ,例如String。

          • void ignoreDependencyInterface(Class<?> ifc) :忽略被給定注入依賴接口 。這個(gè)通常被使用由application contexts去注冊依賴,可以以多種方式實(shí)現(xiàn)。例如BeanFactory通過BeanFactoryAware,ApplicationContext 通過ApplicationContextAware。默認(rèn)情況下,僅BeanFactoryAware接口是被忽略,需要忽略其他接口,調(diào)用此方法。

          • boolean isAutowireCandidate(String beanName,DependencyDescriptor descriptor)throws NoSuchBeanDefinitionException :確認(rèn)這個(gè)被指定的bean是否是一個(gè)autowire候選,將被注入到其他聲明匹配類型的依賴的bean中。

          • isConfigurationFrozen():返回該工廠的bean definnitions是否被凍結(jié)。

          • preInstantiateSingletons():確保所有非懶加載的單例bean被實(shí)例化,包括factoryBeans。

          • void registerResolvableDependency(Class<?> dependencyType,Object autowiredValue):注冊一個(gè)特定類型依賴伴隨著相應(yīng)的autowired值。這個(gè)是準(zhǔn)備被用于應(yīng)該可以autowire而不是在這個(gè)工廠被定義的bean的工廠/上下文引用。例如 將ApplicationContext類型的依賴項(xiàng)解析為Bean所在的ApplicationContext實(shí)例。注意~在普通的BeanFactory中沒有注冊這樣的默認(rèn)類型,甚至連BeanFactory接口本身都沒有。

          postProcessBeanFactory使用示例

          public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
                  // TODO: 2018/6/7 覆蓋屬性值 
                  System.out.println("BeanFactoryPostProcessor調(diào)用postProcessBeanFactory方法");
                  BeanDefinition bd = configurableListableBeanFactory.getBeanDefinition("person");
                  bd.getPropertyValues().addPropertyValue("phone""110");
                  // TODO: 2018/6/7 快速初始化bean 
                  configurableListableBeanFactory.preInstantiateSingletons();
              }

          BeanPostProcessor接口

          允許自定義修改新bean實(shí)例的Factory hook,例如檢查標(biāo)記接口或者把bean包裝成代理。


          ApplicationContext 可以在它們的beans definitions自動(dòng)檢測BeanPostProcessor bean并且把這些bean應(yīng)用于隨后的bean創(chuàng)建。普通的bean factory允許對后處理器進(jìn)行程序化注冊,通過工廠應(yīng)用于所有bean創(chuàng)建。


          BeanPostProcessor 的方法


          • postProcessBeforeInitialization(Object bean, String beanName):在一些bean實(shí)例化回調(diào)(例如InitializingBean的afterPropertiesSet 或者一個(gè)定制的init-method)之前應(yīng)用這個(gè)BeanPostProcessor


          • postProcessAfterInitialization(Object bean, String beanName):在一些bean實(shí)例化回調(diào)(例如InitializingBean的afterPropertiesSet 或者一個(gè)定制的init-method)之后應(yīng)用這個(gè)BeanPostProcessor


          BeanPostProcessor用法示例

              class BeanValidationPostProcessor...
              @Override
              public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                  if (!this.afterInitialization) {
                      doValidate(bean);
                  }
                  return bean;
              }
              /**
               * Perform validation of the given bean.
               * @param bean the bean instance to validate
               * @see javax.validation.Validator#validate
               */
              protected void doValidate(Object bean) {
                  Set<ConstraintViolation<Object>> result = this.validator.validate(bean);
                  if (!result.isEmpty()) {
                      StringBuilder sb = new StringBuilder("Bean state is invalid: ");
                      for (Iterator<ConstraintViolation<Object>> it = result.iterator(); it.hasNext();) {
                          ConstraintViolation<Object> violation = it.next();
                          sb.append(violation.getPropertyPath()).append(" - ").append(violation.getMessage());
                          if (it.hasNext()) {
                              sb.append("; ");
                          }
                      }
                      throw new BeanInitializationException(sb.toString());
                  }
              }

          檢驗(yàn)bean狀態(tài)是否有效。 

          postProcessBeforeInitialization二

          class ApplicationContextAwareProcessor...
          public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
                  AccessControlContext acc = null;

                  if (System.getSecurityManager() != null &&
                          (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
                                  bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
                                  bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
                      acc = this.applicationContext.getBeanFactory().getAccessControlContext();
                  }

                  if (acc != null) {
                      AccessController.doPrivileged(new PrivilegedAction<Object>() {
                          @Override
                          public Object run() {
                              invokeAwareInterfaces(bean);
                              return null;
                          }
                      }, acc);
                  }
                  else {
                      invokeAwareInterfaces(bean);
                  }

                  return bean;
              }

          private void invokeAwareInterfaces(Object bean) {
                  if (bean instanceof Aware) {
                      if (bean instanceof EnvironmentAware) {
                          ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
                      }
                      if (bean instanceof EmbeddedValueResolverAware) {
                          ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(
                                  new EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
                      }
                      if (bean instanceof ResourceLoaderAware) {
                          ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
                      }
                      if (bean instanceof ApplicationEventPublisherAware) {
                          ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
                      }
                      if (bean instanceof MessageSourceAware) {
                          ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
                      }
                      if (bean instanceof ApplicationContextAware) {
                          ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
                      }
                  }
              }

          判斷bean是什么接口,然后進(jìn)行set屬性。應(yīng)該就是api里面說的檢查標(biāo)記接口。 

          大概意識是bean已經(jīng)實(shí)例成功,你可以做一些校驗(yàn)或者補(bǔ)充些內(nèi)容或者把bean包裝代理注入。包裝代理直接把代理實(shí)例返回就行。


          postProcessAfterInitialization和postProcessBeforeInitialization類似。


          InstantiationAwareBeanPostProcessorAdapter

          實(shí)現(xiàn)SmartInstantiationAwareBeanPostProcessor全部方法的適配器,這將不改變由容器正常處理每一個(gè)實(shí)例化的bean。子類僅覆蓋自己想要的方法。


          注意,只有在實(shí)際需要 InstantiationAwareBeanPostProcessor 功能時(shí),才推薦這個(gè)基類。如果您所需要的只是簡單的BeanPostProcessor功能,那么您應(yīng)該選擇直接實(shí)現(xiàn)那個(gè)(更簡單的)接口。

          • postProcessBeforeInstantiation(Class<?> beanClass, String beanName):在實(shí)例化目標(biāo)bean之前應(yīng)用此BeanPostProcessor。這個(gè)返回的bean也許是一個(gè)代理代替目標(biāo)bean,有效地抑制目標(biāo)bean的默認(rèn)實(shí)例化。如果此方法返回一個(gè)非空對象,則bean的創(chuàng)建過程將被短路。唯一的進(jìn)一步處理被應(yīng)用是BeanPostProcessor.postProcessAfterInitialization(java.lang.Object, java.lang.String)方法(可以自己試下,改變了bean的生命周期實(shí)例化之后直接進(jìn)入BeanPostProcessor.postProcessAfterInitialization)回調(diào)來自于配置好的BeanPostProcessors。這個(gè)回調(diào)將僅被應(yīng)用于有bean class的bean defintions。特別是,它不會(huì)應(yīng)用于采用”factory-method“的beans。后處理器可以實(shí)現(xiàn)擴(kuò)展的SmartInstantiationAwareBeanPostProcessor接口,以便預(yù)測它們將返回的bean對象的類型。


          • postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName):在工廠將給定的屬性值應(yīng)用到給定的bean之前,對給定的屬性值進(jìn)行后處理。允許檢查全部依賴是否已經(jīng)全部滿足,例如基于一個(gè)@Required在bean屬性的setter上。還允許替換要應(yīng)用的屬性值,通常通過基于原始的PropertyValues創(chuàng)建一個(gè)新的MutablePropertyValues實(shí)例,添加或刪除特定的值。


          • postProcessAfterInitialization(Object bean, String beanName):在bean初始化回調(diào)(例如:InitializingBean的afterPropertiesSet或者定制的init-method)之后,應(yīng)用這個(gè)BeanPostProcessor去給一個(gè)新的bean實(shí)例。bean已經(jīng)配置了屬性值,返回的bean實(shí)例可能已經(jīng)被包裝。 

          如果是FactoryBean,這個(gè)回調(diào)將為FactoryBean實(shí)例和其他被FactoryBean創(chuàng)建的對象所調(diào)用。這個(gè)post-processor可以通過相應(yīng)的FactoryBean實(shí)例去檢查決定是否應(yīng)用FactoryBean或者被創(chuàng)建的對象或者兩個(gè)都有。 

          這個(gè)回調(diào)在一個(gè)由InstantiationAwareBeanPostProcessor短路的觸發(fā)之后將被調(diào)用。 

          看到這里我也沒看懂是啥意思,下面我們看看源代碼。


          postProcessBeforeInstantiation使用示例

          class AbstractAutoProxyCreator...
           public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
                  Object cacheKey = this.getCacheKey(beanClass, beanName);
                  if(beanName == null || !this.targetSourcedBeans.contains(beanName)) {
                      if(this.advisedBeans.containsKey(cacheKey)) {
                          return null;
                      }

                      if(this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
                          this.advisedBeans.put(cacheKey, Boolean.FALSE);
                          return null;
                      }
                  }

                  if(beanName != null) {
                      TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
                      if(targetSource != null) {
                          this.targetSourcedBeans.add(beanName);
                          Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
                          Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
                          this.proxyTypes.put(cacheKey, proxy.getClass());
                          return proxy;
                      }
                  }

                  return null;
              }

          這個(gè)可以返回代理。


          postProcessPropertyValues使用示例

          示例一

          class RequiredAnnotationBeanPostProcessor ...
          @Override
              public PropertyValues postProcessPropertyValues(
                      PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
                      throws BeansException {

                  if (!this.validatedBeanNames.contains(beanName)) {
                      if (!shouldSkip(this.beanFactory, beanName)) {
                          List<String> invalidProperties = new ArrayList<String>();
                          for (PropertyDescriptor pd : pds) {
                              if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {
                                  invalidProperties.add(pd.getName());
                              }
                          }
                          if (!invalidProperties.isEmpty()) {
                              throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
                          }
                      }
                      this.validatedBeanNames.add(beanName);
                  }
                  return pvs;
              }

          這個(gè)方法很明顯校驗(yàn)需要注入的屬性是否有屬性值。 

          示例二

              @Override
                  public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) {
                      if (bean instanceof EnhancedConfiguration) {
                          ((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
                      }
                      return pvs;
                  }

          在AutowiredAnnotationBeanPostProcessor的postProcessPropertyValues方法試圖自auto-wire其他配置bean之前注入BeanFactory。


          postProcessAfterInitialization使用示例

           public Object postProcessAfterInitialization(Object bean, String beanName) {
                  if(bean instanceof AopInfrastructureBean) {
                      return bean;
                  } else {
                      if(bean instanceof Advised) {
                          Advised advised = (Advised)bean;
                          if(!advised.isFrozen() && this.isEligible(AopUtils.getTargetClass(bean))) {
                              if(this.beforeExistingAdvisors) {
                                  advised.addAdvisor(0, this.advisor);
                              } else {
                                  advised.addAdvisor(this.advisor);
                              }

                              return bean;
                          }
                      }

                      if(this.isEligible(bean, beanName)) {
                          ProxyFactory proxyFactory = new ProxyFactory();
                          proxyFactory.copyFrom(this);
                          proxyFactory.setTarget(bean);
                          if(!proxyFactory.isProxyTargetClass()) {
                              this.evaluateProxyInterfaces(bean.getClass(), proxyFactory);
                          }

                          proxyFactory.addAdvisor(this.advisor);
                          return proxyFactory.getProxy(this.getProxyClassLoader());
                      } else {
                          return bean;
                      }
                  }
              }

          如果bean是一個(gè)基礎(chǔ)的aop bean那么就直接返回,如果不是基礎(chǔ)的aop bean并且實(shí)現(xiàn)了Advise接口那么就對這個(gè)bean進(jìn)行一些操作,如果不是基礎(chǔ)的aop bean沒實(shí)現(xiàn)Advise接口并且是合格的bean就用代理工廠進(jìn)行代理,如果不是基礎(chǔ)的aop bean沒實(shí)現(xiàn)Advise接口并且不是合格的bean那么也直接返回。


          總之對已經(jīng)實(shí)例化的bean進(jìn)行一些處理,可能這個(gè)bean在早期已經(jīng)實(shí)例化了又是單例,那么就銷毀這個(gè)bean用原來的bean。


          BeanNameAware接口

          接口是被實(shí)現(xiàn)由那些想知道其在bean factory中的名稱的bean實(shí)現(xiàn)。請注意,通常不建議對象依賴于它的bean名稱,因?yàn)檫@表示對外部配置的潛在脆弱依賴性,以及對Spring API可能不必要的依賴。

          • setBeanName(String name):在創(chuàng)建這個(gè)bean的bean factory里設(shè)置名字。在填充正常bean屬性之后調(diào)用但是在初始化回調(diào)之前例如InitializingBean的afterPropertiesSet方法或者一個(gè)定制的init-method.

          示例

              class SchedulerFactoryBean ...
              public void setBeanName(String name) {
                  if(this.schedulerName == null) {
                      this.schedulerName = name;
                  }

              }

          對工廠bean進(jìn)行set name


          BeanFactoryAware接口

          接口由希望知道其擁有的BeanFactory的bean實(shí)現(xiàn)。


          例如beans可以通過這個(gè)工廠去查閱和它合作的beans(查閱依賴)。注意大部分beans將選擇通過協(xié)作相應(yīng)bean屬性或者構(gòu)造函數(shù)參數(shù)(依賴注入)去接收協(xié)作beans的引用。


          • setBeanFactory(BeanFactory beanFactory) :為bean實(shí)例提供所屬工廠的回調(diào)。在普通的bean屬性值填充之后但是在初始化回調(diào)之前(例如InitializingBean的afterPropertiesSet方法或者一個(gè)定制的init-method方法)被調(diào)用

          setBeanFactory示例

           public void setBeanFactory(BeanFactory beanFactory) {
                  super.setBeanFactory(beanFactory);
                  if(!(beanFactory instanceof ConfigurableListableBeanFactory)) {
                      throw new IllegalStateException("Cannot use AdvisorAutoProxyCreator without a ConfigurableListableBeanFactory");
                  } else {
                      this.initBeanFactory((ConfigurableListableBeanFactory)beanFactory);
                  }
              }

              protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
                  this.advisorRetrievalHelper = new AbstractAdvisorAutoProxyCreator.BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
              }

          獲得所屬的beanFactory并拷貝到本對象中??梢酝ㄟ^這個(gè)bean所屬的beanFactory檢查bean依賴的bean、beanClassLoader、互斥的單例等。


          InitializingBean接口

          接口被實(shí)現(xiàn)由那些需要響應(yīng)所有已經(jīng)被BeanFactory set的屬性:例如執(zhí)行自定義初始化或者僅檢查是否已經(jīng)set所有必要屬性。


          實(shí)現(xiàn)InitializingBean的另一種方法是指定一個(gè)自定義的init-method,例如在一個(gè)XML配置文件中指定bean的init-method。


          • afterPropertiesSet():在設(shè)置完所有提供的bean屬性(并滿足BeanFactoryAware和ApplicationContextAware)之后由beanFactory調(diào)用。這個(gè)方法允許bean實(shí)例只有在所有的bean屬性都被設(shè)置并且在錯(cuò)誤配置的情況下拋出異常的情況下才能執(zhí)行初始化。

          afterPropertiesSet示例

           

              public void afterPropertiesSet() {
                  if(this.getDataSource() == null) {
                      throw new IllegalArgumentException("Property 'dataSource' is required");
                  }
              }

          檢查是否已經(jīng)set所有必要屬性。

              /**
               * Eagerly create the singleton instance, if necessary.
               */
              @Override
              public void afterPropertiesSet() throws Exception {
                  if (isSingleton()) {
                      this.initialized = true;
                      this.singletonInstance = createInstance();
                      this.earlySingletonInstance = null;
                  }
              }

          這里沒做什么自定義初始化和檢查是否已經(jīng)set所有必要屬性,而是提前初始化單例bean,說明你可以做一些其他操作。


          DisposableBean接口

          接口已經(jīng)被實(shí)現(xiàn)由那些想在銷毀釋放資源的bean。如果BeanFactory處理緩存的單例對象,那么它應(yīng)該調(diào)用destroy方法。 

          應(yīng)用程序上下文在關(guān)閉的時(shí)候應(yīng)該處理它的所有單例。


          實(shí)現(xiàn)InitializingBean的另一種方法是指定一個(gè)自定義的destroy-method,例如在一個(gè)XML配置文件中指定bean的destroy-method。


          destroy示例

          @Override
              public void destroy() {
                  close();
              }

              /**
               * Close this application context, destroying all beans in its bean factory.
               * <p>Delegates to {@code doClose()} for the actual closing procedure.
               * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
               * @see #doClose()
               * @see #registerShutdownHook()
               */
              @Override
              public void close() {
                  synchronized (this.startupShutdownMonitor) {
                      doClose();
                      // If we registered a JVM shutdown hook, we don'
          t need it anymore now:
                      // We've already explicitly closed the context.
                      if (this.shutdownHook != null) {
                          try {
                              Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
                          }
                          catch (IllegalStateException ex) {
                              // ignore - VM is already shutting down
                          }
                      }
                  }
              }

              /**
               * Actually performs context closing: publishes a ContextClosedEvent and
               * destroys the singletons in the bean factory of this application context.
               * <p>Called by both {@code close()} and a JVM shutdown hook, if any.
               * @see org.springframework.context.event.ContextClosedEvent
               * @see #destroyBeans()
               * @see #close()
               * @see #registerShutdownHook()
               */
              protected void doClose() {
                  if (this.active.get() && this.closed.compareAndSet(false, true)) {
                      if (logger.isInfoEnabled()) {
                          logger.info("Closing " + this);
                      }

                      LiveBeansView.unregisterApplicationContext(this);

                      try {
                          // Publish shutdown event.
                          publishEvent(new ContextClosedEvent(this));
                      }
                      catch (Throwable ex) {
                          logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
                      }

                      // Stop all Lifecycle beans, to avoid delays during individual destruction.
                      try {
                          getLifecycleProcessor().onClose();
                      }
                      catch (Throwable ex) {
                          logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
                      }

                      // Destroy all cached singletons in the context'
          s BeanFactory.
                      destroyBeans();

                      // Close the state of this context itself.
                      closeBeanFactory();

                      // Let subclasses do some final clean-up if they wish...
                      onClose();

                      this.active.set(false);
                  }
              }

          執(zhí)行上下文關(guān)閉:發(fā)布一個(gè)ContextClosedEvent和破壞了這個(gè)應(yīng)用上下文的bean工廠中的單例。

          ————————————————

          版權(quán)聲明:本文為CSDN博主「qq_23473123」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。

          原文鏈接:

          https://blog.csdn.net/qq_23473123/article/details/76610052




          鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布

          ??????

          ??長按上方微信二維碼 2 秒





          感謝點(diǎn)贊支持下哈 

          瀏覽 73
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲高清超级无码在线视频观看 | 老阿姨的丝丝波涛胸涌诱惑 | 成人视频免费在线观看黄色视频 | 欧美熟妇另类久久久久久不卡 | 色狼五月 |