在讨论代码细节之前,我们再来了解下基础知识。Spring管理可用于整个应用程序的Java对象bean。他们所在的Spring容器,被称为应用程序上下文。这意味着我们不需要处理他们的生命周期(初始化,销毁)。该任务由此容器来完成。另外,该上下文具有入口点,在Web应用程序中,是dispatcher servlet。容器(也就是该上下文)会在它那里被启动并且所有的bean都会被注入。

说的再清楚点,请看<context:annotation-config />的定义:

<xsd:element name="annotation-config">
 <xsd:annotation>
 <xsd:documentation><![CDATA[
 Activates various annotations to be detected in bean classes: Spring's @Required and
 @Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
 JAX-WS's @WebServiceRef (if available), EJB 3's @EJB (if available), and JPA's
 @PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
 choose to activate the individual BeanPostProcessors for those annotations.
 Note: This tag does not activate processing of Spring's @Transactional or EJB 3's
 @TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
 tag for that purpose.
 See javadoc for org.springframework.context.annotation.AnnotationConfigApplicationContext
 for information on code-based alternatives to bootstrapping annotation-driven support.
 ]]></xsd:documentation>
 </xsd:annotation>
 </xsd:element>

可以看出 : 类内部的注解,如:@Autowired、@Value、@Required、@Resource以及EJB和WebSerivce相关的注解,是容器对Bean对象实例化和依赖注入时,通过容器中注册的Bean后置处理器处理这些注解的。

所以配置了上面这个配置(<context:component-scan>假如有配置这个,那么就可以省略<context:annotation-config />)后,将隐式地向Spring容器注册AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、RequiredAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor以及这4个专门用于处理注解的Bean后置处理器。

当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注解时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。 源码分析如下:

通过org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor可以实现依赖自动注入。通过这个类来处理@Autowired和@Value这俩Spring注解。它也可以管理JSR-303的@Inject注解(如果可用的话)。在AutowiredAnnotationBeanPostProcessor构造函数中定义要处理的注解:

public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
 implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
 ...
 /**
 * Create a new AutowiredAnnotationBeanPostProcessor
 * for Spring's standard {@link Autowired} annotation.
 * <p>Also supports JSR-330's {@link javax.inject.Inject} annotation, if available.
 */
 @SuppressWarnings("unchecked")
 public AutowiredAnnotationBeanPostProcessor() {
 this.autowiredAnnotationTypes.add(Autowired.class);
 this.autowiredAnnotationTypes.add(Value.class);
 try {
 this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
 ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
 logger.info("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
 }
 catch (ClassNotFoundException ex) {
 // JSR-330 API not available - simply skip.
 }
 }
 ...
 }


之后,有几种方法来对@Autowired注解进行处理。

第一个,private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz)解析等待自动注入类的所有属性。它通过分析所有字段和方法并初始化org.springframework.beans.factory.annotation.InjectionMetadata类的实例来实现。

private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
 LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
 Class<?> targetClass = clazz;
 do {
 final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
 //分析所有字段
 ReflectionUtils.doWithLocalFields(targetClass, field -> {
 //findAutowiredAnnotation(field)此方法后面会解释
 AnnotationAttributes ann = findAutowiredAnnotation(field);
 if (ann != null) {
 if (Modifier.isStatic(field.getModifiers())) {
 if (logger.isWarnEnabled()) {
 logger.warn("Autowired annotation is not supported on static fields: " + field);
 }
 return;
 }
 boolean required = determineRequiredStatus(ann);
 currElements.add(new AutowiredFieldElement(field, required));
 }
 });
 //分析所有方法
 ReflectionUtils.doWithLocalMethods(targetClass, method -> {
 Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
 if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
 return;
 }
 AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
 if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
 if (Modifier.isStatic(method.getModifiers())) {
 if (logger.isWarnEnabled()) {
 logger.warn("Autowired annotation is not supported on static methods: " + method);
 }
 return;
 }
 if (method.getParameterCount() == 0) {
 if (logger.isWarnEnabled()) {
 logger.warn("Autowired annotation should only be used on methods with parameters: " +
 method);
 }
 }
 boolean required = determineRequiredStatus(ann);
 PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
 currElements.add(new AutowiredMethodElement(method, required, pd));
 }
 });
 elements.addAll(0, currElements);
 targetClass = targetClass.getSuperclass();
 }
 while (targetClass != null && targetClass != Object.class);
 //返回一个InjectionMetadata初始化的对象实例
 return new InjectionMetadata(clazz, elements);
 }
 ...
 /**
 * 'Native' processing method for direct calls with an arbitrary target instance,
 * resolving all of its fields and methods which are annotated with {@code @Autowired}.
 * @param bean the target instance to process
 * @throws BeanCreationException if autowiring failed
 */
 public void processInjection(Object bean) throws BeanCreationException {
 Class<?> clazz = bean.getClass();
 InjectionMetadata metadata = findAutowiringMetadata(clazz.getName(), clazz, null);
 try {
 metadata.inject(bean, null, null);
 }
 catch (BeanCreationException ex) {
 throw ex;
 }
 catch (Throwable ex) {
 throw new BeanCreationException(
 "Injection of autowired dependencies failed for class [" + clazz + "]", ex);
 }
 }


InjectionMetadata类包含要注入的元素的列表。注入是通过Java的API Reflection (Field set(Object obj, Object value) 或Method invoke(Object obj,Object ... args)方法完成的。此过程直接在AutowiredAnnotationBeanPostProcessor的方法中调用public void processInjection(Object bean) throws BeanCreationException。它将所有可注入的bean检索为InjectionMetadata实例,并调用它们的inject()方法。

public class InjectionMetadata {
 ...
 public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
 Collection<InjectedElement> checkedElements = this.checkedElements;
 Collection<InjectedElement> elementsToIterate =
 (checkedElements != null ? checkedElements : this.injectedElements);
 if (!elementsToIterate.isEmpty()) {
 boolean debug = logger.isDebugEnabled();
 for (InjectedElement element : elementsToIterate) {
 if (debug) {
 logger.debug("Processing injected element of bean '" + beanName + "': " + element);
 }
 //看下面静态内部类的方法
 element.inject(target, beanName, pvs);
 }
 }
 }
 ...
 public static abstract class InjectedElement {
 protected final Member member;
 protected final boolean isField;
 ...
 /**
 * Either this or {@link #getResourceToInject} needs to be overridden.
 */
 protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
 throws Throwable {
 if (this.isField) {
 Field field = (Field) this.member;
 ReflectionUtils.makeAccessible(field);
 field.set(target, getResourceToInject(target, requestingBeanName));
 }
 else {
 if (checkPropertySkipping(pvs)) {
 return;
 }
 try {
 //具体的注入看此处咯
 Method method = (Method) this.member;
 ReflectionUtils.makeAccessible(method);
 method.invoke(target, getResourceToInject(target, requestingBeanName));
 }
 catch (InvocationTargetException ex) {
 throw ex.getTargetException();
 }
 }
 }
 ...
 }
 }


AutowiredAnnotationBeanPostProcessor类中的另一个重要方法是private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao)。它通过分析属于一个字段或一个方法的所有注解来查找@Autowired注解。如果未找到@Autowired注解,则返回null,字段或方法也就视为不可注入。

@Nullable
 private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
 if (ao.getAnnotations().length > 0) {
 for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
 AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
 if (attributes != null) {
 return attributes;
 }
 }
 }
 return null;
 }


在上面的文章中,我们看到了Spring中自动注入过程。通过整篇文章可以看到,这种依赖注入是一种便捷易操作方式(可以在字段以及方法上完成),也促使我们逐渐在抛弃XML配置文件。还增强了代码的可读性。