Spring @Autowired 注解原理
1.@Autowired 使用
@ComponentScan("org.example.bean")
public class AnnoContextDemo {@Autowiredprivate User user;public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnoContextDemo.class);User user1 = context.getBean(AnnoContextDemo.class).user;System.out.println("user1 = " + user1);}}
被扫描的组件配置类
@Configuration
public class BeanConfig {@Beanpublic User user(){return new User(21,"张三");}}
输出结果
user1 = User{age=21, name='张三'}
2.依赖自动注入原理
定位@Autowired所在包 org.springframework.beans.factory.annotation.Autowired
找到同包下 AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor 的类继承图如下
AutowiredAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor与
MergedBeanDefinitionPostProcessor两个BeanPostProcessor后置处理器接口
-
MergedBeanDefinitionPostProcessor 此接口主要有两个方法 抽象方法 postProcessMergedBeanDefinition 默认方法 resetBeanDefinition
-
InstantiationAwareBeanPostProcessor 此接口 抽象方法 postProcessBeforeInstantiation ,postProcessAfterInstantiation ,默认方法 postProcessProperties ,默认过时方法 postProcessPropertyValues
想搞清楚@Autowried注入原理,先得知道这些接口对应方法执行的先后顺序 跟踪ApplicationContext.refresh方法,调用链路如下
ApplicationContext.refresh() -> AbstractApplicationContext.finishBeanFactoryInitialization() -> ConfigurableListableBeanFactory.preInstantiateSingletons() - > AbstractBeanFactory.getBean() -> AbstractBeanFactory.doGetBean() -> AbstractBeanFactory.getSingleton() -> AbstractBeanFactory.createBean()
实例化前
-> resolveBeforeInstantiation() 执行 InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()前置方法 如果返回不为null,将执行 InstantiationAwareBeanPostProcessor.postProcessAfterInitialization()后置方法。
创建bean实例阶段
-> doCreateBean() -> createBeanInstance 反射创建bean实例
-> applyMergedBeanDefinitionPostProcessors() 执行 MergedBeanDefinitionPostProcessor.MergedBeanDefinitionPostProcessor方法 合并bean定义信息
属性注入阶段
-> populateBean() -> 执行 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 后置处理方法 -> 执行InstantiationAwareBeanPostProcessor.postProcessProperties -> InstantiationAwareBeanPostProcessor.postProcessPropertyValues -> applyPropertyValues 执行属性注入
初始化阶段
-> initializeBean() -> BeanPostProcessor.postProcessBeforeInitialization() 执行前置方法 -> invokeInitMethods() 反射调用初始化方法 -> BeanPostProcessor.postProcessAfterInitialization 执行后置方法
收尾注册bean
->registerDisposableBeanIfNecessary() 注册bean
通过上面追踪refresh()方法我们可知,spring容器将先调用 AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition方法,然后执行 postProcessProperties 方法
3. postProcessMergedBeanDefinition 查找需要自动注入的字段或方法
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);metadata.checkConfigMembers(beanDefinition);}
进入findAutowiringMetadata方法
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {// Fall back to class name as cache key, for backwards compatibility with custom callers.String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());// Quick check on the concurrent map first, with minimal locking.InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);if (InjectionMetadata.needsRefresh(metadata, clazz)) {synchronized (this.injectionMetadataCache) {metadata = this.injectionMetadataCache.get(cacheKey);if (InjectionMetadata.needsRefresh(metadata, clazz)) {if (metadata != null) {metadata.clear(pvs);}//查找类的字段,方法,是否有需要自动注入对象的元素,封装InjectionMetadatametadata = buildAutowiringMetadata(clazz);//放入缓存中,供后面调用取出this.injectionMetadataCache.put(cacheKey, metadata);}}}return metadata;}
进入 buildAutowiringMetadata 方法
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {//判断当前类是否有使用autowiredAnnotationTypes容器中的注解if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {return InjectionMetadata.EMPTY;}List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();Class<?> targetClass = clazz;do {final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();//反射遍历类中所有字段ReflectionUtils.doWithLocalFields(targetClass, field -> {//字段上是否有标注自动装配相关的注解MergedAnnotation<?> ann = findAutowiredAnnotation(field);if (ann != null) {if (Modifier.isStatic(field.getModifiers())) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static fields: " + field);}return;}boolean required = determineRequiredStatus(ann);//封装InjectionMetadatacurrElements.add(new AutowiredFieldElement(field, required));}});//反射遍历类中所有方法ReflectionUtils.doWithLocalMethods(targetClass, method -> {Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {return;}//方法上是否有标注自动装配相关的注解MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {if (Modifier.isStatic(method.getModifiers())) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static methods: " + method);}return;}if (method.getParameterCount() == 0) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation should only be used on methods with parameters: " +method);}}boolean required = determineRequiredStatus(ann);PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);//封装InjectionMetadatacurrElements.add(new AutowiredMethodElement(method, required, pd));}});elements.addAll(0, currElements);targetClass = targetClass.getSuperclass();}while (targetClass != null && targetClass != Object.class);return InjectionMetadata.forElements(elements, clazz);}
this.autowiredAnnotationTypes 为set集合,容器内为需要自动注入的注解类
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
public AutowiredAnnotationBeanPostProcessor() {## 1.@Autowiredthis.autowiredAnnotationTypes.add(Autowired.class);## 2.@Valuethis.autowiredAnnotationTypes.add(Value.class);try {## 3.@javax.inject.Inject JSR-330规范中定义的一个注解this.autowiredAnnotationTypes.add((Class<? extends Annotation>)ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");}catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}}
4.postProcessProperties 需要自动注入的元素从容器中获取bean后注入
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {//首先从缓存中取出需要自动注入的元素(包括字段,方法)InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);try {//进行注入metadata.inject(bean, beanName, pvs);}catch (BeanCreationException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);}return pvs;}
进入 metadata.inject() 方法
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()) {//遍历需要注入的元素for (InjectedElement element : elementsToIterate) {//不同类型调用各自inject方法element.inject(target, beanName, pvs);}}}
字段处理逻辑
通过 resolveFieldValue 方法,找到需要依赖的bean(单个或集合),通过 Filed.set方法注入
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {Field field = (Field) this.member;Object value;if (this.cached) {try {value = resolvedCachedArgument(beanName, this.cachedFieldValue);}catch (NoSuchBeanDefinitionException ex) {// Unexpected removal of target bean for cached argument -> re-resolvevalue = resolveFieldValue(field, bean, beanName);}}else {//查找依赖的beanvalue = resolveFieldValue(field, bean, beanName);}if (value != null) {ReflectionUtils.makeAccessible(field);//反射设置值field.set(bean, value);}}
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);try {Object shortcut = descriptor.resolveShortcut(this);if (shortcut != null) {return shortcut;}Class<?> type = descriptor.getDependencyType();Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);if (value != null) {if (value instanceof String) {String strVal = resolveEmbeddedValue((String) value);BeanDefinition bd = (beanName != null && containsBean(beanName) ?getMergedBeanDefinition(beanName) : null);value = evaluateBeanDefinitionString(strVal, bd);}TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());try {return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());}catch (UnsupportedOperationException ex) {// A custom TypeConverter which does not support TypeDescriptor resolution...return (descriptor.getField() != null ?converter.convertIfNecessary(value, type, descriptor.getField()) :converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));}}Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);if (multipleBeans != null) {return multipleBeans;}//字段非集合类型时bean时查找方法Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);if (matchingBeans.isEmpty()) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}return null;}String autowiredBeanName;Object instanceCandidate;if (matchingBeans.size() > 1) {autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);}else {// In case of an optional Collection/Map, silently ignore a non-unique case:// possibly it was meant to be an empty collection of multiple regular beans// (before 4.3 in particular when we didn't even look for collection beans).return null;}}instanceCandidate = matchingBeans.get(autowiredBeanName);}else {// We have exactly one match.Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();autowiredBeanName = entry.getKey();instanceCandidate = entry.getValue();}if (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);}if (instanceCandidate instanceof Class) {instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);}Object result = instanceCandidate;if (result instanceof NullBean) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);}result = null;}if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());}return result;}finally {ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);}}
findAutowireCandidates() 会调用 BeanFactoryUtils.beanNamesForTypeIncludingAncestors
底层通过类似双亲委派模型,找出所有的bean
public static String[] beanNamesForTypeIncludingAncestors(ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {Assert.notNull(lbf, "ListableBeanFactory must not be null");String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);if (lbf instanceof HierarchicalBeanFactory) {HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {String[] parentResult = beanNamesForTypeIncludingAncestors((ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);result = mergeNamesWithParent(result, parentResult, hbf);}}return result;}