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
