婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁(yè) > 知識(shí)庫(kù) > Spring Annotaion Support詳細(xì)介紹及簡(jiǎn)單實(shí)例

Spring Annotaion Support詳細(xì)介紹及簡(jiǎn)單實(shí)例

熱門標(biāo)簽:泰州泰興400電話 怎么申請(qǐng) 企業(yè)怎么在聯(lián)通申請(qǐng)400電話 如何用中國(guó)地圖標(biāo)注數(shù)字點(diǎn) 百度地圖添加標(biāo)注圖標(biāo)樣式 南京新思維電話機(jī)器人 南昌市地圖標(biāo)注app 聊城智能電銷機(jī)器人外呼 地圖標(biāo)注市場(chǎng)怎么樣 好操作的電話機(jī)器人廠家

     最近正在看spring官網(wǎng),看Spring IOC的時(shí)候看Spring容器擴(kuò)展點(diǎn)的時(shí)候發(fā)現(xiàn)了BeanPostProcessor 這個(gè)接口。下面是官方對(duì)它的詳細(xì)描述:

          BeanPostProcessor接口定義了回調(diào)方法,您可以實(shí)現(xiàn)提供自己的(或覆蓋容器的默認(rèn))實(shí)例化邏輯,依賴性解析邏輯,等等。如果你想實(shí)現(xiàn)一些自定義邏輯Spring容器實(shí)例化完成后,配置和初始化一個(gè)bean,您可以插入一個(gè)或多個(gè)BeanPostProcessor實(shí)現(xiàn)。

          您可以配置多個(gè)BeanPostProcessor實(shí)例,您可以控制的順序執(zhí)行這些BeanPostProcessors通過(guò)設(shè)置屬性。你可以設(shè)置這個(gè)屬性只有BeanPostProcessor實(shí)現(xiàn)命令接口;如果你寫自己的BeanPostProcessor你也應(yīng)該考慮實(shí)現(xiàn)theOrdered接口。詳情,請(qǐng)咨詢BeanPostProcessor的Javadoc和命令接口。

          BeanPostProcessor有兩個(gè)方法postProcessBeforeInitialization,postProcessAfterInitialization.如果一個(gè)對(duì)象實(shí)現(xiàn)了這個(gè)接口,那么就會(huì)在容器初始化init方法之前(就像InitializingBean的afterPropertiesSet()和其它公開的init方法)或在Spring bean初始化之后執(zhí)行回調(diào)。

          實(shí)現(xiàn)BeanPostProcessor接口的類由容器是特殊而區(qū)別對(duì)待。所有BeanPostProcessors和他們?cè)趩?dòng)時(shí)直接引用實(shí)例化bean,作為特殊的ApplicationContext的啟動(dòng)階段。接下來(lái),所有BeanPostProcessorsare注冊(cè)分類的方式,適用于所有進(jìn)一步bean容器。因?yàn)閷?shí)現(xiàn)AOP auto-proxying aBeanPostProcessor本身,無(wú)論是BeanPostProcessors還是beas他們有資格獲得auto-proxying直接引用,因此沒(méi)有方面編織進(jìn)去。

          實(shí)現(xiàn)BeanPostProcessor接口的類由容器是特殊而區(qū)別對(duì)待。所有BeanPostProcessors和他們?cè)趩?dòng)時(shí)直接引用實(shí)例化bean,作為特殊的ApplicationContext的啟動(dòng)階段。接下來(lái),所有BeanPostProcessorsare注冊(cè)分類的方式,適用于所有進(jìn)一步bean容器。因?yàn)閷?shí)現(xiàn)AOP auto-proxying aBeanPostProcessor本身,無(wú)論是BeanPostProcessors還是beas他們有資格獲得auto-proxying直接引用,因此沒(méi)有方面編織進(jìn)去。

          使用回調(diào)接口或注釋與自定義實(shí)現(xiàn)BeanPostProcessor是一種常見(jiàn)的擴(kuò)展SpringIoC容器。RequiredAnnotationBeanPostProcessor是Spring的一個(gè)例子 —— 一個(gè)實(shí)現(xiàn)BeanPostProcessor附帶的Spring分布,確保JavaBean屬性bean上標(biāo)有一個(gè)(任意)注釋(配置)會(huì)依賴注入值。

你說(shuō)我一看到上面的AOP這個(gè)Spring兩大特性之一我心里面都有一點(diǎn)小激動(dòng)。后面他再來(lái)個(gè)Spring的Annotation一般也是用這個(gè)接口實(shí)現(xiàn)的。這下就忍不住了想去看一看RequiredAnnotationBeanPostProcessor這個(gè)類到底干了什么。直接上源碼

Spring Annotation Support 
 
/* 
 * Copyright 2002-2013 the original author or authors. 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0 
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 */ 
 
package org.springframework.beans.factory.annotation; 
 
import java.beans.PropertyDescriptor; 
import java.lang.annotation.Annotation; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 
import java.util.Set; 
import java.util.concurrent.ConcurrentHashMap; 
 
import org.springframework.beans.BeansException; 
import org.springframework.beans.PropertyValues; 
import org.springframework.beans.factory.BeanFactory; 
import org.springframework.beans.factory.BeanFactoryAware; 
import org.springframework.beans.factory.BeanInitializationException; 
import org.springframework.beans.factory.config.BeanDefinition; 
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; 
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; 
import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor; 
import org.springframework.beans.factory.support.RootBeanDefinition; 
import org.springframework.core.Conventions; 
import org.springframework.core.Ordered; 
import org.springframework.core.PriorityOrdered; 
import org.springframework.core.annotation.AnnotationUtils; 
import org.springframework.util.Assert; 
 
/** 
 * {@link org.springframework.beans.factory.config.BeanPostProcessor} implementation 
 * that enforces required JavaBean properties to have been configured. 
 * 強(qiáng)制檢測(cè)JavaBean必須的properties是否已經(jīng)被配置 
 * Required bean properties are detected through a Java 5 annotation: 
 * 必須的bean屬性通過(guò)Java 5中的annotation自動(dòng)檢測(cè)到 
 * by default, Spring's {@link Required} annotation. 
 * 
 * p>The motivation for the existence of this BeanPostProcessor is to allow 
 * BeanPostProcessor存在的意義是允許 
 * developers to annotate the setter properties of their own classes with an 
 * arbitrary JDK 1.5 annotation to indicate that the container must check 
 * for the configuration of a dependency injected value. This neatly pushes 
 * 開發(fā)人員注釋setter屬性與一個(gè)他們自己的類任意的JDK 1.5注釋表明容器必須檢查依賴注入的配置值。 
 * responsibility for such checking onto the container (where it arguably belongs), 
 * 這樣就巧妙的把check的責(zé)任給了Spring容器(它應(yīng)該就屬于的) 
 * and obviates the need (b>in part/b>) for a developer to code a method that 
 * simply checks that all required properties have actually been set. 
 * 這樣也就排除了開發(fā)人員需要編寫一個(gè)簡(jiǎn)單的方法用來(lái)檢測(cè)那么必須的properties是否已經(jīng)設(shè)置了值 
 * p>Please note that an 'init' method may still need to implemented (and may 
 * still be desirable), because all that this class does is enforce that a 
 * 請(qǐng)注意初始化方法還是必須要實(shí)現(xiàn)的(并且仍然是可取的) 
 * 'required' property has actually been configured with a value. It does 
 * 因?yàn)樗羞@個(gè)Class強(qiáng)制執(zhí)行的是'required'屬性是否已經(jīng)被配置了值 
 * b>not/b> check anything else... In particular, it does not check that a 
 * 它并不會(huì)check其實(shí)的事,特別的是,它不會(huì)check這個(gè)配置的值是不是null值 
 * configured value is not {@code null}. 
 * 
 * p>Note: A default RequiredAnnotationBeanPostProcessor will be registered 
 * by the "context:annotation-config" and "context:component-scan" XML tags. 
 * 當(dāng)你使用了"context:annotation-config"或者"context:component-scan"XML標(biāo)簽就會(huì)默認(rèn)注冊(cè)RequiredAnnotationBeanPostProcessor 
 * Remove or turn off the default annotation configuration there if you intend 
 * to specify a custom RequiredAnnotationBeanPostProcessor bean definition. 
 * 你如果打算指定一個(gè)自定義的RequiredAnnotationBeanPostProcessor的bean實(shí)現(xiàn)可以移除或者關(guān)閉默認(rèn)的annotation配置 
 * 
 * @author Rob Harrop 
 * @author Juergen Hoeller 
 * @since 2.0 
 * @see #setRequiredAnnotationType 
 * @see Required 
 */ 
public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter 
    implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { 
 
  /** 
   * Bean definition attribute that may indicate whether a given bean is supposed 
   * to be skipped when performing this post-processor's required property check. 
   * 這個(gè)bean定義的屬性表明當(dāng)執(zhí)行post-processor(后處理程序)這個(gè)check提供的bean的必須的屬性 
   * @see #shouldSkip 
   */ 
  public static final String SKIP_REQUIRED_CHECK_ATTRIBUTE = 
      Conventions.getQualifiedAttributeName(RequiredAnnotationBeanPostProcessor.class, "skipRequiredCheck"); 
 
 
  private Class? extends Annotation> requiredAnnotationType = Required.class; 
 
  private int order = Ordered.LOWEST_PRECEDENCE - 1; 
 
  private ConfigurableListableBeanFactory beanFactory; 
 
  /** 
   * Cache for validated bean names, skipping re-validation for the same bean 
   * 緩存已經(jīng)確認(rèn)過(guò)的bean名稱,跳過(guò)后續(xù)同樣的bean 
   */ 
  private final SetString> validatedBeanNames = 
      Collections.newSetFromMap(new ConcurrentHashMapString, Boolean>(64)); 
 
 
  /** 
   * Set the 'required' annotation type, to be used on bean property 
   * setter methods. 
   * 設(shè)置所需的注釋類型,使用bean屬性setter方法 
   * p>The default required annotation type is the Spring-provided 
   * {@link Required} annotation. 
   * 這個(gè)默認(rèn)的required annotation類型是Spring提供的annotation 
   * p>This setter property exists so that developers can provide their own 
   * (non-Spring-specific) annotation type to indicate that a property value 
   * is required. 
   * 這里設(shè)置這個(gè)property是為了開發(fā)者能夠提供自己定義的annotaion類型用來(lái)表明這個(gè)屬性值是必須的 
   */ 
  public void setRequiredAnnotationType(Class? extends Annotation> requiredAnnotationType) { 
    Assert.notNull(requiredAnnotationType, "'requiredAnnotationType' must not be null"); 
    this.requiredAnnotationType = requiredAnnotationType; 
  } 
 
  /** 
   * Return the 'required' annotation type. 
   */ 
  protected Class? extends Annotation> getRequiredAnnotationType() { 
    return this.requiredAnnotationType; 
  } 
 
  @Override 
  public void setBeanFactory(BeanFactory beanFactory) { 
    if (beanFactory instanceof ConfigurableListableBeanFactory) { 
      this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; 
    } 
  } 
 
  public void setOrder(int order) { 
    this.order = order; 
  } 
 
  @Override 
  public int getOrder() { 
    return this.order; 
  } 
 
 
  @Override 
  public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class?> beanType, String beanName) { 
  } 
 
  @Override 
  public PropertyValues postProcessPropertyValues( 
      PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) 
      throws BeansException { 
    // 利用緩存確定是否這個(gè)bean被validated 
    if (!this.validatedBeanNames.contains(beanName)) { 
      // 不跳過(guò) 
      if (!shouldSkip(this.beanFactory, beanName)) { 
        ListString> invalidProperties = new ArrayListString>(); 
        for (PropertyDescriptor pd : pds) { 
          // 如果被標(biāo)記為了required 且 這個(gè)屬性沒(méi)有屬性值(或其他處理?xiàng)l目) 
          if (isRequiredProperty(pd)  !pvs.contains(pd.getName())) { 
            // 增加這個(gè)屬性 
            invalidProperties.add(pd.getName()); 
          } 
        } 
        // span style="color:#ff0000;">如果無(wú)效的properties不為空。拋出異常/span> 
        if (!invalidProperties.isEmpty()) { 
          throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName)); 
        } 
      } 
      // 把需要驗(yàn)證的bean名稱添加進(jìn)去 
      this.validatedBeanNames.add(beanName); 
    } 
    return pvs; 
  } 
 
  /** 
   * Check whether the given bean definition is not subject to the annotation-based 
   * required property check as performed by this post-processor. 
   * 通過(guò)post-processor(后處理程序)檢測(cè)這個(gè)被給予的定義的bean是否受注釋為基礎(chǔ)的check必須的property的管束 
   * p>The default implementations check for the presence of the 
   * {@link #SKIP_REQUIRED_CHECK_ATTRIBUTE} attribute in the bean definition, if any. 
   * 這個(gè)默認(rèn)的實(shí)現(xiàn)check存在SKIP_REQUIRED_CHECK_ATTRIBUTE這個(gè)屬性的定義的bean 
   * It also suggests skipping in case of a bean definition with a "factory-bean" 
   * reference set, assuming that instance-based factories pre-populate the bean. 
   * 它同樣也建議跳過(guò)如果這個(gè)bean定義了"factory-bean"引用,假設(shè)那個(gè)基于實(shí)例的factories預(yù)先配置了bean 
   * @param beanFactory the BeanFactory to check against 
   * @param beanName the name of the bean to check against 
   * @return {@code true} to skip the bean; {@code false} to process it 
   * 如果返回 true跳過(guò)這個(gè)bean,返回false就處理它 
   */ 
  protected boolean shouldSkip(ConfigurableListableBeanFactory beanFactory, String beanName) { 
    // 如果這個(gè)beanFacotry為空或者這個(gè)bean工廠不包含一個(gè)給定名稱的bean定義。返回false 
    if (beanFactory == null || !beanFactory.containsBeanDefinition(beanName)) { 
      return false; 
    } 
    BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); 
    // 判斷這個(gè)bean的工廠beanName,如果不為null,返回true 
    if (beanDefinition.getFactoryBeanName() != null) { 
      return true; 
    } 
    Object value = beanDefinition.getAttribute(SKIP_REQUIRED_CHECK_ATTRIBUTE); 
    return (value != null  (Boolean.TRUE.equals(value) || Boolean.valueOf(value.toString()))); 
  } 
 
  /** 
   * Is the supplied property required to have a value (that is, to be dependency-injected)? 
   * 是否這個(gè)提供的必須的propery是否有一個(gè)值(這個(gè)是被依賴注入)? 
   * p>This implementation looks for the existence of a 
   * {@link #setRequiredAnnotationType "required" annotation} 
   * on the supplied {@link PropertyDescriptor property}. 
   * 這個(gè)實(shí)現(xiàn)是為了找到提供的ProertyDescriptor是提供了"required"注解 
   * @param propertyDescriptor the target PropertyDescriptor (never {@code null}) 
   * @return {@code true} if the supplied property has been marked as being required; 
   * 返回true,如果提供的property已經(jīng)被標(biāo)記為必須的/span> 
   * {@code false} if not, or if the supplied property does not have a setter method 
   * 返回false,如果沒(méi)有標(biāo)記為必須的或者提供的property沒(méi)有一個(gè)setter方法 
   */ 
  protected boolean isRequiredProperty(PropertyDescriptor propertyDescriptor) { 
    Method setter = propertyDescriptor.getWriteMethod(); 
    return (setter != null  AnnotationUtils.getAnnotation(setter, getRequiredAnnotationType()) != null); 
  } 
 
  /** 
   * Build an exception message for the given list of invalid properties. 
   * 使用所給的異常properties來(lái)構(gòu)建異常信息 
   * @param invalidProperties the list of names of invalid properties 
   * @param beanName the name of the bean 
   * @return the exception message 
   */ 
  private String buildExceptionMessage(ListString> invalidProperties, String beanName) { 
    int size = invalidProperties.size(); 
    StringBuilder sb = new StringBuilder(); 
    sb.append(size == 1 ? "Property" : "Properties"); 
    for (int i = 0; i  size; i++) { 
      String propertyName = invalidProperties.get(i); 
      if (i > 0) { 
        if (i == (size - 1)) { 
          sb.append(" and"); 
        } 
        else { 
          sb.append(","); 
        } 
      } 
      sb.append(" '").append(propertyName).append("'"); 
    } 
    sb.append(size == 1 ? " is" : " are"); 
    sb.append(" required for bean '").append(beanName).append("'"); 
    return sb.toString(); 
  } 
 
} 

在上面的代碼中所示。我們可以得出以下結(jié)論:

上面已經(jīng)把Spring對(duì)于 org.springframework.beans.factory.annotation.Required 這個(gè)標(biāo)簽的實(shí)現(xiàn)出來(lái)了。雖然只是一個(gè)小例子。但是我們可以根據(jù)Spring以下的的包結(jié)構(gòu)看到這是Spring對(duì)于它自身Annotation的很common的實(shí)現(xiàn):

從上面的例子中我可以看出Spring對(duì)它本身的Annotaion的一種實(shí)現(xiàn)。當(dāng)前文中并沒(méi)有講述Exception Message是通過(guò)怎么傳遞的。但是這并不是本文討論的范疇,有興趣的朋友可以自己去看看。

感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!

標(biāo)簽:白銀 臨汾 自貢 吉林 銅川 山南 開封 烏蘭察布

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Spring Annotaion Support詳細(xì)介紹及簡(jiǎn)單實(shí)例》,本文關(guān)鍵詞  Spring,Annotaion,Support,詳細(xì),;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Spring Annotaion Support詳細(xì)介紹及簡(jiǎn)單實(shí)例》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于Spring Annotaion Support詳細(xì)介紹及簡(jiǎn)單實(shí)例的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    主站蜘蛛池模板: 剑阁县| 阳山县| 九江县| 榆树市| 梅河口市| 宜兰市| 九江市| 霍州市| 永定县| 安吉县| 玉屏| 荥经县| 德庆县| 岳西县| 浦江县| 东阳市| 铜鼓县| 原阳县| 敦煌市| 永德县| 香港| 花垣县| 奎屯市| 临洮县| 青川县| 乐清市| 大新县| 巫山县| 横峰县| 吉林省| 田林县| 开阳县| 固镇县| 徐水县| 蓝山县| 甘孜| 三都| 奈曼旗| 玉龙| 武定县| 襄垣县|