您的位置:首页 > 编程语言 > Java开发

spring注解源码分析--how does autowired works?

2016-06-12 11:18 537 查看
1. 背景

注解可以减少代码的开发量,spring提供了丰富的注解功能。我们可能会被问到,spring的注解到底是什么触发的呢?今天以spring最常使用的一个注解autowired来跟踪代码,进行debug。

2. Autowired的定义及作用

作用:Marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities.

定义:

@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;

}


2.1 @Target

首先,@Target起到什么作用呢?我们来看jdk的说明:

Indicates the kinds of program element to which an annotation type is applicable. If a Target meta-annotation is not present on an annotation type declaration, the declared type may be used on any program element. If such a meta-annotation is present, the compiler will enforce the specified usage restriction.

其次,@Target定义:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}


注解表明适用于哪种程序元素,程序元素有以下几种:

public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,

/** Field declaration (includes enum constants) */
FIELD,

/** Method declaration */
METHOD,

/** Parameter declaration */
PARAMETER,

/** Constructor declaration */
CONSTRUCTOR,

/** Local variable declaration */
LOCAL_VARIABLE,

/** Annotation type declaration */
ANNOTATION_TYPE,

/** Package declaration */
PACKAGE
}


最后,Target使用方式:

@Target(value={ANNOTATION_TYPE})

2.2 @Retention

首先,作用:Indicates how long annotations with the annotated type are to be retained. If no Retention annotation is present on an annotation type declaration, the retention policy defaults to RetentionPolicy.CLASS

简单的说就是作用域

然后我们看其定义:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
RetentionPolicy value();
}


最后,使用方式:

@Retention(value=RetentionPolicy )

RetentionPolicy 作用域定义

public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,

/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time.  This is the default
* behavior.
*/
CLASS,

/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}


2.3.@Documented

作用:Indicates that annotations with a type are to be documented by javadoc and similar tools by default. This type should be used to annotate the declarations of types whose annotations affect the use of annotated elements by their clients. If a type declaration is annotated with Documented, its annotations become part of the public API of the annotated elements.简单的说,可以成为api的一部分。

定义:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}


使用:@Documented

3.注解实现类AutowiredAnnotationBeanPostProcessor的注册

它的注册过程如下:



注册的注解相关处理器代码如下:

/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, Object source) {

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}

return beanDefs;
}


通过代码,我们可以看到注册的注解处理器有:

org.springframework.context.annotation.internalConfigurationAnnotationProcessor对应于ConfigurationClassPostProcessor

org.springframework.context.annotation.internalAutowiredAnnotationProcessor对应于AutowiredAnnotationBeanPostProcessor

org.springframework.context.annotation.internalRequiredAnnotationProcessor对应于RequiredAnnotationBeanPostProcessor

org.springframework.context.annotation.internalCommonAnnotationProcessor对应于CommonAnnotationBeanPostProcessor

org.springframework.context.annotation.internalPersistenceAnnotationProcessor对应于PersistenceAnnotationBeanPostProcessor

4.注解实现类AutowiredAnnotationBeanPostProcessor使用

构造方法的调用链

AbstractAutowireCapableBeanFactory#createBean()-->AbstractAutowireCapableBeanFactory#doCreateBean()-->

AbstractAutowireCapableBeanFactory#createBeanInstance()-->

AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors()-->

AutowiredAnnotationBeanPostProcessor#determineConstructorsFromBeanPostProcessors()

基于成员变量的注解自动注入

AbstractAutowireCapableBeanFactory#createBean()-->AbstractAutowireCapableBeanFactory#doCreateBean()-->

AbstractAutowireCapableBeanFactory#populateBean()-->AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues()-->

InjectionMetadata#inject()-->AutowiredFieldElement#inject()/AutowiredMethodElement#inject()

5.小结

Spring框架从创建伊始就致力于为复杂问题提供强大的、非侵入性的解决方案。开始时Spring使用XML配置文件数量引入定制命名空间功能。

Spring 2.5推出了一整套注解,作为基于XML的配置的可选方案。注解可用于Spring管理对象的自动发现、依赖注入、生命周期方法、Web层配置和单元/集成测试。

   spring注解确实提高了开发效率,但一直以来,对spring注解的工作原理都处于一知半解的状态,使用注解过程中碰到问题,也是通过搜索或者多次尝试的方式来验证,为了更好的工作,趁着有时间把how spring annotation works这件事做起来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: