@Autowired注解使用及原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangguosb/article/details/84594129

使用说明

数组或集合的注入

  Spring容器中所有了类型匹配的bean都被注入进来,并且如果bean有@Order注解或者实现Order接口,按照Order的先后顺序注入;

Map的注入

  • key的类型必须为String,注入后值为bean的名称;
  • value类型即为想要注入的bean类,所有类型匹配的bean会被注入进来;

In case of a {@link java.util.Collection} or {@link java.util.Map} dependency type, the container autowires all beans matching the declared value type. For such purposes, the map keys must be declared as type String which will be resolved to the corresponding bean names. Such a container-provided collection will be ordered, taking into account {@link org.springframework.core.Ordered}/{@link org.springframework.core.annotation.Order} values of the target components, otherwise following their registration order in the container. Alternatively, a single matching target bean may also be a generally typed {@code Collection} or {@code Map} itself, getting injected as such.

父类属性的注入

  应用场景:父类或抽象类中存在公共依赖的bean时;

public abstract class AbstractTest {
    @Autowired
    private TestService1 testService1;

    public abstract void test();

    public TestService1 getTestService1() {
        return testService1;
    }

    public void setTestService1(TestService1 testService1) {
        this.testService1 = testService1;
    }
}
@Component
public class TestImpl extends AbstractTest{

    @Autowired
    private TestService2 testService2;

    public TestImpl(){
        System.out.println("TestImpl()");
    }

    @Override
    public void test() {
        testService2.t2();
        TestService1 testService1 = this.getTestService1();
        testService1.t1();
    }
}

required属性

  required属性值可以为true( 默认值)和false。如果为true的话,没有匹配的类则抛出异常;如果为false,则表示不是强制必须能够找到相应的类,无论是否注入成功,都不会抛错。

工作原理

 注解解析器:AutowiredAnnotationBeanPostProcessor

  1. Spring容器启动时,AutowiredAnnotationBeanPostProcessor被注册到容器;
  2. 扫描代码,如果带有@Autowired注解,则将依赖注入信息封装到InjectionMetadata中(见扫描过程);
  3. 创建bean时(实例化对象和初始化),会调用各种BeanPostProcessor对bean初始化,AutowiredAnnotationBeanPostProcessor负责将相关的依赖注入进来;

@Autowired扫描过程

  1. 扫描当前类中标注@Autowired的属性和方法;
  2. 再查找父类中注@Autowired的属性和方法,依次遍历;
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 -> {
				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);

参考:

  1. https://juejin.im/entry/5ad3fda5f265da238d512a98

猜你喜欢

转载自blog.csdn.net/yangguosb/article/details/84594129