Spring注入 @Autowired和setter方式区别原理
pring 的注入方式有:setter、constructor、静态工厂方法、实例工厂方法、注解@Autowired自动装配几种方式。
今天我们要了解的是:setter和@Autowired两种方式的区别,常用的setter方式很好理解,通过调用Bean的属性setter方法直观的赋值即可。而@Autowired方式,没有setter方法赋值又是通过什么方式实现的呢?看一下spring源码:
1、AbstractAutowireCapableBeanFactory类中的autowireBean()方法
populateBean()方法:
2、AutowiredAnnotationBeanPostProcessor类中通过postProcessPropertyValues()方法很容易找到内部类AutowiredFieldElement.inject()方法:
通过上面的代码很容易了解到,@Autowired方式是通过反射来设置属性值的,噢。。。。。。。。。万能而无节操的反射,明白了吧
@Autowired注解使用及原理
required属性
required属性值可以为true( 默认值)和false。如果为true的话,没有匹配的类则抛出异常;如果为false,则表示不是强制必须能够找到相应的类,无论是否注入成功,都不会抛错。
工作原理
注解解析器:AutowiredAnnotationBeanPostProcessor
Spring容器启动时,AutowiredAnnotationBeanPostProcessor被注册到容器;
扫描代码,如果带有@Autowired注解,则将依赖注入信息封装到InjectionMetadata中(见扫描过程);
创建bean时(实例化对象和初始化),会调用各种BeanPostProcessor对bean初始化,AutowiredAnnotationBeanPostProcessor负责将相关的依赖注入进来;
Spring 创建对象分为三个过程:
1、创建对象实例 Object obj = new Object() 或者 Object obj = new Object(xxx);
AbstractAutowireCapableBeanFactory#createBeanInstance
2、依赖注入: obj.setXxx(xxx) {多个属性就是 foreach}
AbstractAutowireCapableBeanFactory#populateBean
3、Spring bean 扩展方法:init-method,BeanPostProcess,XXXAware 扩展
AbstractAutowireCapableBeanFactory#initializeBean
@Autowired扫描过程
- 扫描当前类中标注@Autowired的属性和方法;
- 再查找父类中注@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);
参考文章:
https://blog.csdn.net/wenluoxicheng/article/details/73608657