亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JSP > 正文

Spring Annotaion Support詳細介紹及簡單實例

2020-07-27 21:24:36
字體:
來源:轉載
供稿:網友

     最近正在看spring官網,看Spring IOC的時候看Spring容器擴展點的時候發現了BeanPostProcessor 這個接口。下面是官方對它的詳細描述:

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

          您可以配置多個BeanPostProcessor實例,您可以控制的順序執行這些BeanPostProcessors通過設置屬性。你可以設置這個屬性只有BeanPostProcessor實現命令接口;如果你寫自己的BeanPostProcessor你也應該考慮實現theOrdered接口。詳情,請咨詢BeanPostProcessor的Javadoc和命令接口。

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

          實現BeanPostProcessor接口的類由容器是特殊而區別對待。所有BeanPostProcessors和他們在啟動時直接引用實例化bean,作為特殊的ApplicationContext的啟動階段。接下來,所有BeanPostProcessorsare注冊分類的方式,適用于所有進一步bean容器。因為實現AOP auto-proxying aBeanPostProcessor本身,無論是BeanPostProcessors還是beas他們有資格獲得auto-proxying直接引用,因此沒有方面編織進去。

          實現BeanPostProcessor接口的類由容器是特殊而區別對待。所有BeanPostProcessors和他們在啟動時直接引用實例化bean,作為特殊的ApplicationContext的啟動階段。接下來,所有BeanPostProcessorsare注冊分類的方式,適用于所有進一步bean容器。因為實現AOP auto-proxying aBeanPostProcessor本身,無論是BeanPostProcessors還是beas他們有資格獲得auto-proxying直接引用,因此沒有方面編織進去。

          使用回調接口或注釋與自定義實現BeanPostProcessor是一種常見的擴展SpringIoC容器。RequiredAnnotationBeanPostProcessor是Spring的一個例子 ―― 一個實現BeanPostProcessor附帶的Spring分布,確保JavaBean屬性bean上標有一個(任意)注釋(配置)會依賴注入值。

你說我一看到上面的AOP這個Spring兩大特性之一我心里面都有一點小激動。后面他再來個Spring的Annotation一般也是用這個接口實現的。這下就忍不住了想去看一看RequiredAnnotationBeanPostProcessor這個類到底干了什么。直接上源碼

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.  * 強制檢測JavaBean必須的properties是否已經被配置  * Required bean properties are detected through a Java 5 annotation:  * 必須的bean屬性通過Java 5中的annotation自動檢測到  * 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  * 開發人員注釋setter屬性與一個他們自己的類任意的JDK 1.5注釋表明容器必須檢查依賴注入的配置值。  * responsibility for such checking onto the container (where it arguably belongs),  * 這樣就巧妙的把check的責任給了Spring容器(它應該就屬于的)  * 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.  * 這樣也就排除了開發人員需要編寫一個簡單的方法用來檢測那么必須的properties是否已經設置了值  * <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  * 請注意初始化方法還是必須要實現的(并且仍然是可取的)  * 'required' property has actually been configured with a value. It does  * 因為所有這個Class強制執行的是'required'屬性是否已經被配置了值  * <b>not</b> check anything else... In particular, it does not check that a  * 它并不會check其實的事,特別的是,它不會check這個配置的值是不是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.  * 當你使用了"context:annotation-config"或者"context:component-scan"XML標簽就會默認注冊RequiredAnnotationBeanPostProcessor  * Remove or turn off the default annotation configuration there if you intend  * to specify a custom RequiredAnnotationBeanPostProcessor bean definition.  * 你如果打算指定一個自定義的RequiredAnnotationBeanPostProcessor的bean實現可以移除或者關閉默認的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.    * 這個bean定義的屬性表明當執行post-processor(后處理程序)這個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    * 緩存已經確認過的bean名稱,跳過后續同樣的bean    */   private final Set<String> validatedBeanNames =       Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(64));     /**    * Set the 'required' annotation type, to be used on bean property    * setter methods.    * 設置所需的注釋類型,使用bean屬性setter方法    * <p>The default required annotation type is the Spring-provided    * {@link Required} annotation.    * 這個默認的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.    * 這里設置這個property是為了開發者能夠提供自己定義的annotaion類型用來表明這個屬性值是必須的    */   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 {     // 利用緩存確定是否這個bean被validated     if (!this.validatedBeanNames.contains(beanName)) {       // 不跳過       if (!shouldSkip(this.beanFactory, beanName)) {         List<String> invalidProperties = new ArrayList<String>();         for (PropertyDescriptor pd : pds) {           // 如果被標記為了required 且 這個屬性沒有屬性值(或其他處理條目)           if (isRequiredProperty(pd) && !pvs.contains(pd.getName())) {             // 增加這個屬性             invalidProperties.add(pd.getName());           }         }         // <span style="color:#ff0000;">如果無效的properties不為空。拋出異常</span>         if (!invalidProperties.isEmpty()) {           throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));         }       }       // 把需要驗證的bean名稱添加進去       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.    * 通過post-processor(后處理程序)檢測這個被給予的定義的bean是否受注釋為基礎的check必須的property的管束    * <p>The default implementations check for the presence of the    * {@link #SKIP_REQUIRED_CHECK_ATTRIBUTE} attribute in the bean definition, if any.    * 這個默認的實現check存在SKIP_REQUIRED_CHECK_ATTRIBUTE這個屬性的定義的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.    * 它同樣也建議跳過如果這個bean定義了"factory-bean"引用,假設那個基于實例的factories預先配置了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跳過這個bean,返回false就處理它    */   protected boolean shouldSkip(ConfigurableListableBeanFactory beanFactory, String beanName) {     // 如果這個beanFacotry為空或者這個bean工廠不包含一個給定名稱的bean定義。返回false     if (beanFactory == null || !beanFactory.containsBeanDefinition(beanName)) {       return false;     }     BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);     // 判斷這個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)?    * 是否這個提供的必須的propery是否有一個值(這個是被依賴注入)?    * <p>This implementation looks for the existence of a    * {@link #setRequiredAnnotationType "required" annotation}    * on the supplied {@link PropertyDescriptor property}.    * 這個實現是為了找到提供的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已經被標記為必須的</span>    * {@code false} if not, or if the supplied property does not have a setter method    * 返回false,如果沒有標記為必須的或者提供的property沒有一個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來構建異常信息    * @param invalidProperties the list of names of invalid properties    * @param beanName the name of the bean    * @return the exception message    */   private String buildExceptionMessage(List<String> 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();   }  } 

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

111

上面已經把Spring對于 org.springframework.beans.factory.annotation.Required 這個標簽的實現出來了。雖然只是一個小例子。但是我們可以根據Spring以下的的包結構看到這是Spring對于它自身Annotation的很common的實現:

11

從上面的例子中我可以看出Spring對它本身的Annotaion的一種實現。當前文中并沒有講述Exception Message是通過怎么傳遞的。但是這并不是本文討論的范疇,有興趣的朋友可以自己去看看。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情久久久久| 国外视频精品毛片| 疯狂做受xxxx高潮欧美日本| 亚洲国产精品成人va在线观看| 日韩三级影视基地| 亚洲欧美日韩国产精品| www.国产一区| 亚洲丝袜av一区| 国产精品av免费在线观看| 97国产精品久久| 日韩精品欧美国产精品忘忧草| 色樱桃影院亚洲精品影院| 欧美激情一区二区三区高清视频| 亚洲性av网站| 亚洲欧美精品一区二区| 国产视频亚洲精品| 日韩欧美一区二区三区久久| 国产激情久久久久| 91久久久久久久久| 在线午夜精品自拍| 国产91在线高潮白浆在线观看| 性日韩欧美在线视频| 精品国产欧美一区二区五十路| 欧美日产国产成人免费图片| 97视频在线观看视频免费视频| 国产精品aaaa| 成人精品在线视频| 国产一级揄自揄精品视频| 91理论片午午论夜理片久久| 欧美亚洲国产成人精品| 91精品视频在线免费观看| 8x拔播拔播x8国产精品| 亚洲国产天堂久久国产91| 欧美日本国产在线| 日韩欧美在线看| 国产精品久久久久久一区二区| 欧美在线xxx| 深夜精品寂寞黄网站在线观看| 91av网站在线播放| 国产伦精品一区二区三区精品视频| 欧美黑人狂野猛交老妇| 欧美富婆性猛交| 亚洲第一色中文字幕| 富二代精品短视频| 国产一区二区三区日韩欧美| 亚洲欧美中文字幕| 日韩精品日韩在线观看| 秋霞av国产精品一区| 尤物yw午夜国产精品视频明星| 国产欧美日韩精品在线观看| 欧美一区二粉嫩精品国产一线天| 成人激情在线观看| 日韩欧美a级成人黄色| 81精品国产乱码久久久久久| 亚洲国产精品va在线看黑人| 精品亚洲va在线va天堂资源站| 有码中文亚洲精品| 国产一区二区三区中文| 国产欧美日韩综合精品| 91国在线精品国内播放| 国内精品视频在线| 91久久精品国产91久久性色| 精品久久久久久久久国产字幕| 国产精品精品一区二区三区午夜版| 亚洲综合在线播放| 亚洲电影免费观看高清完整版在线| 欧美日韩福利视频| 欧美国产一区二区三区| 国产成人jvid在线播放| 粉嫩av一区二区三区免费野| 欧美在线激情网| 亚洲精品av在线| 日韩在线观看免费高清| 亚洲人成绝费网站色www| 神马久久久久久| 久久精品视频免费播放| 国产精品欧美风情| 亚洲片在线观看| 日韩动漫免费观看电视剧高清| 国产亚洲a∨片在线观看| 色偷偷噜噜噜亚洲男人| 国产精品自产拍在线观| 亚洲国产欧美日韩精品| 亚洲国产精品中文| 亚洲成人激情在线观看| 91啪国产在线| 国产精品久久久久久久久久久不卡| 国产精品直播网红| 久久亚洲影音av资源网| 2021久久精品国产99国产精品| 国产精品v片在线观看不卡| 亚洲精品不卡在线| 欧美日韩国产影院| 亚洲综合社区网| 欧美日韩免费在线观看| 亚洲天堂av网| 日本一区二区在线免费播放| 亚洲精品色婷婷福利天堂| 亚洲精品久久久一区二区三区| 欧美日韩国产一区在线| 亚洲欧美日韩国产中文| 久久久国产成人精品| 国产精品国产三级国产专播精品人| 日本久久精品视频| 亚洲国产成人久久综合| 人人爽久久涩噜噜噜网站| 日韩在线播放视频| 国内精品模特av私拍在线观看| 亚洲欧美国产精品va在线观看| 欧美国产日韩在线| 国产aⅴ夜夜欢一区二区三区| 精品久久久久久中文字幕一区奶水| 久久久亚洲网站| 播播国产欧美激情| 大桥未久av一区二区三区| 亚洲sss综合天堂久久| 日本欧美在线视频| 韩国19禁主播vip福利视频| 日韩亚洲综合在线| 久久精品视频免费播放| 97久久精品人搡人人玩| 久久天堂av综合合色| 亚洲精品久久久久久久久久久久| 国产在线拍偷自揄拍精品| 久久偷看各类女兵18女厕嘘嘘| 国产精品免费久久久久久| 欧美华人在线视频| 91系列在线播放| 蜜臀久久99精品久久久无需会员| 中文字幕亚洲精品| 久久国产加勒比精品无码| 欧美日韩国产丝袜另类| 亚洲国产精品久久91精品| 久久精品国产一区二区三区| 久久免费视频在线| 国产精品99久久久久久久久| 伊人久久男人天堂| 中文字幕国产日韩| 国产精品成人免费电影| 亚洲欧美一区二区三区四区| 91精品国产自产在线观看永久| 最近中文字幕2019免费| 国产一区二区三区中文| 色综合久久中文字幕综合网小说| 亚洲男人的天堂网站| 欧美精品videofree1080p| 久久网福利资源网站| 久久久日本电影| 亚洲欧美日韩视频一区| 91精品视频免费看| 国产精品69久久久久| 国产精品99免视看9| 国产精品久久久久999| 亚洲精品美女在线观看| 欧美在线一区二区视频| 国产精品欧美一区二区三区奶水| 国产成人精品久久二区二区| 中国人与牲禽动交精品| 97色在线视频| 成人免费网站在线观看| 国内精品久久久久久中文字幕| 久久久精品网站| 成人精品视频久久久久| 久久久久国色av免费观看性色|