spring beans源码解读之--Bean的注解(annotation)
隨著spring注解的引入,越來越多的開發(fā)者開始使用注解,這篇文章將對(duì)注解的機(jī)制進(jìn)行串聯(lián)式的講解,不求深入透徹,但求串起spring beans注解的珍珠,展示給大家。
1. spring beans常用的注解:
? public @interface Autowired:可以對(duì)成員變量、方法和構(gòu)造函數(shù)進(jìn)行標(biāo)注,來完成自動(dòng)裝配的工作。
Marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities. Only one constructor (at max) of any given bean class may carry this annotation, indicating the constructor to autowire when used as a Spring bean. Such a constructor does not have to be public.Fields are injected right after construction of a bean, before any config methods are invoked. Such a config field does not have to be public.Config methods may have an arbitrary name and any number of arguments; each of those arguments will be autowired with a matching bean in the Spring container. Bean property setter methods are effectively just a special case of such a general config method. Such config methods do not have to be public.In the case of multiple argument methods, the 'required' parameter is applicable for all arguments.In case of a Collection or Map dependency type, the container will autowire all beans matching the declared value type. In case of a Map, the keys must be declared as type String and will be resolved to the corresponding bean names.Note that actual injection is performed through a BeanPostProcessor which in turn means that you cannot use @Autowired to inject references into BeanPostProcessor or BeanFactoryPostProcessor types. Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor class (which, by default, checks for the presence of this annotation). Since: 2.5? public @interface Configurable?@Configurable?注解中的autowire屬性就可以讓Spring來自動(dòng)裝配了:?@Configurable(autowire=Autowire.BY_TYPE)?或者?@Configurable(autowire=Autowire.BY_NAME,這樣就可以按類型或者按名字自動(dòng)裝配了。
Marks a class as being eligible for Spring-driven configuration. Typically used with the AspectJ AnnotationBeanConfigurerAspect.Since: 2.0 public @interface Value:用于注入SpEL表達(dá)式,可以放置在字段方法或參數(shù)上。Annotation at the field or method/constructor parameter level that indicates a default value expression for the affected argument. Typically used for expression-driven dependency injection. Also supported for dynamic resolution of handler method parameters, e.g. in Spring MVC.A common use case is to assign default field values using "#{systemProperties.myProp}" style expressions.Note that actual processing of the @Value annotation is performed by a BeanPostProcessor which in turn means that you cannot use @Value within BeanPostProcessor or BeanFactoryPostProcessor types. Please consult the javadoc for the AutowiredAnnotationBeanPostProcessor class (which, by default, checks for the presence of this annotation).Since: 3.0 public @interface Qualifier:指定限定描述符,對(duì)應(yīng)于基于XML配置中的<qualifier>標(biāo)簽,@Qualifier限定描述符除了能根據(jù)名字進(jìn)行注入,但能進(jìn)行更細(xì)粒度的控制如何選擇候選者
@Qualifier(value = "限定標(biāo)識(shí)符")?。 This annotation may be used on a field or parameter as a qualifier for candidate beans when autowiring. It may also be used to annotate other custom annotations that can then in turn be used as qualifiers. Since: 2.5 public @interface Required 依賴檢查; Marks a method (typically a JavaBean setter method) as being 'required': that is, the setter method must be configured to be dependency-injected with a value. Please do consult the javadoc for the RequiredAnnotationBeanPostProcessor class (which, by default, checks for the presence of this annotation).Since: 2.0
?
2. 注解bean的定義AnnotatedBeanDefinition
public interface AnnotatedBeanDefinition extends BeanDefinition {/*** Obtain the annotation metadata (as well as basic class metadata)* for this bean definition's bean class.* @return the annotation metadata object (never {@code null})*/AnnotationMetadata getMetadata();}? ?該接口繼承了BeanDefinition,提供了一個(gè)getMetadata()方法來獲取該bean definition的注解元數(shù)據(jù)。
其中,AnnotationMetadata定義了訪問特定類的注解的抽象接口,它不需要加載該類即可訪問。
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata { } ClassMetadata定義了一個(gè)特定類的抽象元數(shù)據(jù),不需要加載此類。主要方法如下:String getClassName()返回該類的名稱。boolean isInterface()返回該類是否是接口。boolean isAbstract()返回該類是否為抽象類。boolean isConcrete()返回該類是否為具體類。boolean isFinal()返回該類是否為final類boolean hasSuperClass()返回該類是否有父類 String getSuperClassName()返回父類的名稱,沒有的話返回null. String[] getInterfaceNames()返回繼承的接口數(shù)組,如果沒有,返回空. String[] getMemberClassNames()返回引用的類的名稱。
AnnotatedTypeMetadata定義訪問特定類型的注解,不需要加載類。主要方法有:
boolean isAnnotated(String annotationType)是否有匹配的注解類型 Map<String,Object> getAnnotationAttributes(String annotationType,boolean classValuesAsString)獲取特定類型注解的屬性AnnotationMetadata的標(biāo)準(zhǔn)實(shí)現(xiàn)類StandardAnnotationMetadata,它使用標(biāo)準(zhǔn)的反射來獲取制定類的內(nèi)部注解信息。主要方法有:
getAllAnnotationAttributes(String annotationType) getAnnotatedMethods(String annotationType) hasMetaAnnotation(String annotationType) isAnnotated(String annotationType) hasAnnotatedMethods(String annotationType)AnnotationMetadata還有一個(gè)子類:AnnotationMetadataReadingVisitor,它是字節(jié)碼訪問實(shí)現(xiàn)。
class ClassMetadataReadingVisitor extends ClassVisitor implements ClassMetadata { }讓我們了解一下visitor模式:
定義:
The?Gang of Four?defines the Visitor as:?"Represent an operation to be performed on elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates."—″≤
The nature of the Visitor makes it an ideal pattern to plug into public APIs thus allowing its clients to perform operations on a class using a “visiting” class without having to modify the source.
uml 結(jié)構(gòu)圖如下:
?小結(jié):vistor設(shè)置模式把狀態(tài)抽象出來成為一個(gè)接口(訪問者),不同的狀態(tài)就作為狀態(tài)的不同實(shí)現(xiàn)類(不同的訪問者)。
?3.?注解bean的實(shí)現(xiàn)類
? ? 3.1?AnnotatedGenericBeanDefinition
? ? ? ? ? 繼承了GenericBeanDefinition,增加了對(duì)注解元素的支持,這種支持是通過AnnotationBeanDefinition暴露的的注解元素接口。
?GenericBeanDefinition主要用來測(cè)試AnnotatedBeanDefinition上的操作的,例如:在spring的component掃描支持的實(shí)現(xiàn)中(默認(rèn)實(shí)現(xiàn)類是ScannedGenericBeanDefinition,它同樣實(shí)現(xiàn)了AnnotatedBeanDefinition接口)
? 3.2?ConfigurationClassBeanDefinition
? ??ConfigurationClassBeanDefinition是ConfigurationClassBeanDefinitionReader的內(nèi)部類,ConfigurationClassBeanDefinitionReader讀取一組完全填充了屬性的配置實(shí)例,通過context內(nèi)給定的BeanDefinitionRegistry進(jìn)行注冊(cè)bean definition。這個(gè)類在BeanDefinitionReader這層后就改造,但沒有繼承或者擴(kuò)展配置類。
? ?3.3?ScannedGenericBeanDefinition
? 基于asm的類解析器,是GenericBeanDefinition類的擴(kuò)展,支持注解元數(shù)據(jù),這種支持通過AnnotatedBeanDefinition接口實(shí)現(xiàn)。
4. 注解的解析與處理
4.1 @Autowired注解實(shí)現(xiàn)AutowiredAnnotationBeanPostProcessor
?
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapterimplements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { } AutowiredAnnotationBeanPostProcessor 間接繼承了BeanPostProcessor,它自動(dòng)綁定注解的field,setter方法和任意的配置方法。當(dāng)檢測(cè)到5個(gè)java注解時(shí)這些成員被注入其中。spring默認(rèn)的注解為@Autowired和@Value。另外:也支持JSR-330的@inject注解,作為@Autowired的替代方案。
當(dāng)制定bean 類的唯一構(gòu)造方法帶有required 注解參數(shù),且required值設(shè)置為true時(shí),表明當(dāng)作為spring一個(gè)bean時(shí),構(gòu)造方法默認(rèn)自動(dòng)綁定。若多個(gè)構(gòu)造方法帶有non-required 注解參數(shù),它們將作為自動(dòng)綁定的候選項(xiàng)。帶有大量依賴的構(gòu)造方法可以通過spring容器中的匹配的bean來構(gòu)造,如果沒有候選者滿足條件,則會(huì)使用默認(rèn)的構(gòu)造器。注解構(gòu)造器不一定是public的。
Field注入是在構(gòu)造方法之后,配置方法之前,這種配置field不要求一定為public
配置方法可以有任意的名稱和不定的參數(shù)列表,這些參數(shù)則被自動(dòng)注入到spring容器中的匹配的bean。bean的屬性setter方法僅僅是通用的配置方法的一個(gè)特例而已。配置方法不要求方法一定為public
注意:默認(rèn)注冊(cè)AutowiredAnnotationBeanPostProcessor的方式有<context:annotation-config> 和<context:component-scan> xml標(biāo)簽,如果你指定了一個(gè)自定義的AutowiredAnnotationBeanPostProcessor bean definition,移除或者關(guān)閉默認(rèn)的注解配置。
其中,MergedBeanDefinitionPostProcessor的定義如下: public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {/*** Post-process the given merged bean definition for the specified bean.* @param beanDefinition the merged bean definition for the bean* @param beanType the actual type of the managed bean instance* @param beanName the name of the bean*/void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);} BeanPostProcessor 是一個(gè)可以定制修改一個(gè)新的bean實(shí)例的工廠鉤子,例如:檢查marker接口或者使用代理包裝他們。
applicationContext可以在他們的bean容器中自動(dòng)識(shí)別BeanPostProcessor bean,并將它們應(yīng)用到接下來所創(chuàng)建的bean。一般的bean factory通過編程來注冊(cè)Post-processor,并將它們應(yīng)用到整個(gè)bean factory創(chuàng)建bean的過程中。
通常意義上,post-processor 設(shè)置bean屬性通過marker 接口或者類似于實(shí)現(xiàn)postProcessBeforeInitialization(java.lang.Object, java.lang.String);使用代理包裝bean通常實(shí)現(xiàn)postProcessAfterInitialization(java.lang.Object, java.lang.String).
4.2 @configurable注解實(shí)現(xiàn)AnnotationBeanWiringInfoResolver?
設(shè)置?@Configurable?注解中的autowire屬性就可以讓Spring來自動(dòng)裝配了:?@Configurable(autowire=Autowire.BY_TYPE)?或者?@Configurable(autowire=Autowire.BY_NAME,這樣就可以按類型或者按名字自動(dòng)裝配了。
? ??AnnotationBeanWiringInfoResolver 繼承自BeanWiringInfoResolver,BeanWiringInfoResolver使用configurable注解來查找哪些類需要自動(dòng)綁定。
public class AnnotationBeanWiringInfoResolver implements BeanWiringInfoResolver { }實(shí)現(xiàn)了BeanWiringInfoResolver的resolveWiringInfo方法
@Overridepublic BeanWiringInfo resolveWiringInfo(Object beanInstance) {Assert.notNull(beanInstance, "Bean instance must not be null");Configurable annotation = beanInstance.getClass().getAnnotation(Configurable.class);return (annotation != null ? buildWiringInfo(beanInstance, annotation) : null);}/*** Build the BeanWiringInfo for the given Configurable annotation.* @param beanInstance the bean instance* @param annotation the Configurable annotation found on the bean class* @return the resolved BeanWiringInfo*/protected BeanWiringInfo buildWiringInfo(Object beanInstance, Configurable annotation) {if (!Autowire.NO.equals(annotation.autowire())) {return new BeanWiringInfo(annotation.autowire().value(), annotation.dependencyCheck());}else {if (!"".equals(annotation.value())) {// explicitly specified bean namereturn new BeanWiringInfo(annotation.value(), false);}else {// default bean namereturn new BeanWiringInfo(getDefaultBeanName(beanInstance), true);}}}?4.3 @qualifier的注解實(shí)現(xiàn)類QualifierAnnotationAutowireCandidateResolver
?
public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwareAutowireCandidateResolver { }public class GenericTypeAwareAutowireCandidateResolver implements AutowireCandidateResolver, BeanFactoryAware { }其中,AutowireCandidateResolver是一個(gè)策略接口,由它來決定特定的bean definition對(duì)特定的依賴是否可以作為一個(gè)自動(dòng)綁定的候選項(xiàng),它的主要方法有:
boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor)
Object getLazyResolutionProxyIfNecessary(DependencyDescriptor descriptor,String beanName)
Object getSuggestedValue(DependencyDescriptor descriptor)
?QualifierAnnotationAutowireCandidateResolver間接實(shí)現(xiàn)了AutowireCandidateResolver,對(duì)要自動(dòng)綁定的field或者參數(shù)和bean definition根據(jù)@qualifier注解進(jìn)行匹配。同時(shí)也支持通過@value注解來綁定表達(dá)式的值。
另外,還只是JSR-330的javax.inject.Qualifier注解。
4.4 @required注解實(shí)現(xiàn)類RequiredAnnotationBeanPostProcessor。
public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapterimplements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware { }和AutowiredAnnotationBeanPostProcessor一樣,間接繼承自BeanPostProcessor,它增加了對(duì)javaBean屬性配置的約束,java 5 注解可以檢測(cè)bean的required屬性,spring默認(rèn)是@Required注解。
注意:默認(rèn)注冊(cè)AutowiredAnnotationBeanPostProcessor的方式有<context:annotation-config> 和<context:component-scan> xml標(biāo)簽,如果你指定了一個(gè)自定義的 默認(rèn)注冊(cè)AutowiredAnnotationBeanPostProcessor的方式有<context:annotation-config> 和<context:component-scan> xml標(biāo)簽,如果你指定了一個(gè)自定義的AutowiredAnnotationBeanPostProcessor bean definition,移除或者關(guān)閉默認(rèn)的注解配置。其余和AutowiredAnnotationBeanPostProcessor類似,不一一贅述了。4.5 初始化和銷毀方法的注解實(shí)現(xiàn)類InitDestroyAnnotationBeanPostProcessor
public class InitDestroyAnnotationBeanPostProcessorimplements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable { }InitDestroyAnnotationBeanPostProcessor間接繼承了BeanPostProcess,實(shí)現(xiàn)了通過注解來初始化和銷毀方法,是spring的InitializingBean和DisposableBean回調(diào)接口的注解實(shí)現(xiàn)。
它通過"initAnnotationType"和"destroyAnnotationType"屬性來檢查指定的注解類型,任何自定義的注解都可以使用。
初始化和銷毀注解可以用在任意可見的方法:public,package-protected,protected,private等。盡管可以對(duì)多個(gè)方法進(jìn)行注解,但我們推薦只在一個(gè)初始化和銷毀方法上各自進(jìn)行注解。
?
小結(jié):
?Spring3的基于注解實(shí)現(xiàn)Bean依賴注入支持如下三種注解:
Spring自帶依賴注入注解: Spring自帶的一套依賴注入注解;
JSR-250注解:Java平臺(tái)的公共注解,是Java EE 5規(guī)范之一,在JDK6中默認(rèn)包含這些注解,從Spring2.5開始支持。
JSR-330注解:Java 依賴注入標(biāo)準(zhǔn),Java EE 6規(guī)范之一,可能在加入到未來JDK版本,從Spring3開始支持;
其中,
Spring自帶依賴注入注解
1 @Required:依賴檢查;
2 @Autowired:自動(dòng)裝配2?
自動(dòng)裝配,用于替代基于XML配置的自動(dòng)裝配
基于@Autowired的自動(dòng)裝配,默認(rèn)是根據(jù)類型注入,可以用于構(gòu)造器、字段、方法注入
3 @Value:注入SpEL表達(dá)式
用于注入SpEL表達(dá)式,可以放置在字段方法或參數(shù)上
@Value(value = "SpEL表達(dá)式") ?
@Value(value = "#{message}") ?
4 @Qualifier:限定描述符,用于細(xì)粒度選擇候選者
@Qualifier限定描述符除了能根據(jù)名字進(jìn)行注入,但能進(jìn)行更細(xì)粒度的控制如何選擇候選者
@Qualifier(value = "限定標(biāo)識(shí)符")?
JSR-250注解
1 @Resource:自動(dòng)裝配,默認(rèn)根據(jù)類型裝配,如果指定name屬性將根據(jù)名字裝配,可以使用如下方式來指定
@Resource(name = "標(biāo)識(shí)符") ?
字段或setter方法?
2 @PostConstruct和PreDestroy:通過注解指定初始化和銷毀方法定義
?
JSR-330注解
1 @Inject:等價(jià)于默認(rèn)的@Autowired,只是沒有required屬性
2 @Named:指定Bean名字,對(duì)應(yīng)于Spring自帶@Qualifier中的缺省的根據(jù)Bean名字注入情況
3 @Qualifier:只對(duì)應(yīng)于Spring自帶@Qualifier中的擴(kuò)展@Qualifier限定描述符注解,即只能擴(kuò)展使用,沒有value屬性
1. http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/beans/factory/annotation/
2. http://blog.csdn.net/wangshfa/article/details/9712379
?
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/4199459.html
總結(jié)
以上是生活随笔為你收集整理的spring beans源码解读之--Bean的注解(annotation)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kafka Windows客户端Linu
- 下一篇: 项目中使用Quartz集群分享--转载