文章目录
- 前言
- 一、注解的装配收集
- 二、属性的依赖注入
- 三、bean实例化后置处理
- 3.1.调用Aware方法
- 3.2.对类中某些特殊方法的调用,比如@PostConstruct
- 3.3.调用InitMethod方法
- 3.4.调用postProcessAfterInitialization方法
- 总结
前言
上篇文章讲过了Spring实例化bean调用类的构造方法,但只是在堆内存中分配一块内存空间,但是类中的属性还没有注入到对象中,这篇文章着重讲解依赖注入的过程……
一、注解的装配收集
1
2
3
4
5
6
7
8
9
10
11
12
13// 这个方法主要完成对类中注解的收集工作 protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { // 循环遍历所有的BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { //调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法 if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; //收集到所有的注解信息封装到InjectionMetadata中 bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
循环遍历所有的MergedBeanDefinitionPostProcessor,主要有以下几种用于对注解的收集:
- AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value注解的收集
- CommonAnnotationBeanPostProcessor:处理@Resource注解的收集
- InitDestroyAnnotationBeanPostProcessor:处理@PostConstruct、@PreDestroy注解的收集
我们以AutowiredAnnotationBeanPostProcessor为例具体看看是怎么进行注解的收集工作的?
1
2
3
4
5
6public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { // 注解的信息封装到InjectionMetadata中 InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); }
继续看findAutowiringMetadata方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) { // 缓存key值 String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName()); // 首先检查injectionMetadataCache缓存中是否有值,有则直接返回 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); } // 注解信息的主要封装过程 metadata = buildAutowiringMetadata(clazz); // 放到缓存里面,以后需要用到注解的话直接从缓存中拿即可 this.injectionMetadataCache.put(cacheKey, metadata); } } } return metadata; }
接下里我们看,注解信息的主要封装过程buildAutowiringMetadata方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { // 如果类中没有相关注解,则返回空 if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) { return InjectionMetadata.EMPTY; } // InjectedElement类型的集合 List<InjectionMetadata.InjectedElement> elements = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>(); // 寻找field上面的@Autowire注解并封装成对象 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); // 将属性方面的的注解封装成AutowiredFieldElement放到currElements集合中 // AutowiredFieldElement为InjectedElement的子类 currElements.add(new AutowiredFieldElement(field, required)); } }); // 寻找method上面的@Autowire注解并封装成对象 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); //封装成AutowiredMethodElement放到currElements集合中 // AutowiredMethodElement是InjectedElement的子类 currElements.add(new AutowiredMethodElement(method, required, pd)); } }); //final修饰的currElements中的值放到elements中 elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); //封装成InjectionMetadata return InjectionMetadata.forElements(elements, clazz); }
我们在对属性进行依赖注入的时候,推荐使用@Resource注解,因为@Resource注解是JDK支持的,那么我们来看看Spring对@Resource的处理
1
2
3
4
5
6
7public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName); // 处理@Resource注解的收集 InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null); metadata.checkConfigMembers(beanDefinition); }
经过跟踪源码,整体流程和对@Autowired的处理大同小异,但不同的是调用了父类的
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName)
这里又是做了些什么呢?
1
2
3
4
5
6public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) { // 处理@PostConstruct、@PreDestroy注解的收集 LifecycleMetadata metadata = findLifecycleMetadata(beanType); metadata.checkConfigMembers(beanDefinition); }
继续看findLifecycleMetadata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) { if (this.lifecycleMetadataCache == null) { // Happens after deserialization, during destruction... return buildLifecycleMetadata(clazz); } // 缓存中获取 LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz); if (metadata == null) { synchronized (this.lifecycleMetadataCache) { metadata = this.lifecycleMetadataCache.get(clazz); if (metadata == null) { // 主要处理方法 metadata = buildLifecycleMetadata(clazz); // 放到缓存中 this.lifecycleMetadataCache.put(clazz, metadata); } return metadata; } } return metadata; }
接着来看buildLifecycleMetadata方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) { // 如果没有注解则返回空 if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) { return this.emptyLifecycleMetadata; } List<LifecycleElement> initMethods = new ArrayList<>(); List<LifecycleElement> destroyMethods = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<LifecycleElement> currInitMethods = new ArrayList<>(); final List<LifecycleElement> currDestroyMethods = new ArrayList<>(); ReflectionUtils.doWithLocalMethods(targetClass, method -> { //initAnnotationType是@PostConstruct注解 if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) { LifecycleElement element = new LifecycleElement(method); currInitMethods.add(element); if (logger.isTraceEnabled()) { logger.trace("Found init method on class [" + clazz.getName() + "]: " + method); } } // destroyAnnotationType是@preDestroy注解 if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) { currDestroyMethods.add(new LifecycleElement(method)); if (logger.isTraceEnabled()) { logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method); } } }); initMethods.addAll(0, currInitMethods); destroyMethods.addAll(currDestroyMethods); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata : new LifecycleMetadata(clazz, initMethods, destroyMethods)); }
二、属性的依赖注入
1
2
3
4
5applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); | >这个名字起的就非常有意思,填充bean, populateBean(beanName, mbd, instanceWrapper);
看看这个方法的具体操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { // 对bw的校验 if (bw == null) { if (mbd.hasPropertyValues()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } //在设置属性之前,让任何InstantiationAwareBeanPostProcessors都有机会修改Bean的状态。 if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { //实现InstantiationAwareBeanPostProcessor接口 if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 是否需要DI if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } //postProcessPropertyValues是属于弃用状态,暂不关注 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // @Autowire支持依赖注入的过程,主要看这里 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // 老版本用这个完成依赖注入的过程,@Autowire的支持 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } // 标签做依赖注入的代码实现,复杂且无用 if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); } }
进入postProcessProperties方法,这个方法是一个钩子方法,直接看实现类
AutowiredAnnotationBeanPostProcessor.postProcessProperties
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { //这个方法是不是很熟悉呢,在注解收集的时候调用过,所以这里直接从缓存中拿到InjectionMetadata 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(bean, beanName, pvs);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15public 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) { if (logger.isTraceEnabled()) { logger.trace("Processing injected element of bean '" + beanName + "': " + element); } // 遍历每一个节点的反射方法 element.inject(target, beanName, pvs); } } }
进入到子类AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement的inject方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50/** * inject 依赖注入的最终反射实现 */ protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable { Field field = (Field) this.member; Object value; if (this.cached) { value = resolvedCachedArgument(beanName, this.cachedFieldValue); } else { DependencyDescriptor desc = new DependencyDescriptor(field, this.required); desc.setContainingClass(bean.getClass()); Set<String> autowiredBeanNames = new LinkedHashSet<>(1); Assert.state(beanFactory != null, "No BeanFactory available"); TypeConverter typeConverter = beanFactory.getTypeConverter(); try { value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } catch (BeansException ex) { throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex); } synchronized (this) { if (!this.cached) { if (value != null || this.required) { this.cachedFieldValue = desc; registerDependentBeans(beanName, autowiredBeanNames); if (autowiredBeanNames.size() == 1) { String autowiredBeanName = autowiredBeanNames.iterator().next(); if (beanFactory.containsBean(autowiredBeanName) && beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { this.cachedFieldValue = new ShortcutDependencyDescriptor( desc, autowiredBeanName, field.getType()); } } } else { this.cachedFieldValue = null; } this.cached = true; } } } if (value != null) { // 字段设置为可访问的 ReflectionUtils.makeAccessible(field); // 最终field的依赖注入通过反射实现 field.set(bean, value); } }
方法的依赖注入与字段的类似,调用的子类AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement的inject方法,这里不多做赘述。
三、bean实例化后置处理
bean实例化并且IOC依赖注入完成之后,调用
1
2exposedObject = initializeBean(beanName, exposedObject, mbd);
该方法都做了哪些事情呢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 1.调用Aware方法 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // 2.对类中某些特殊方法的调用,比如@PostConstruct、Aware接口 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 3.调用InitMethod方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 4.调用BeanPostProcessor的postProcessAfterInitialization方法 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
下面分别从方法中注释的4点进行分析
3.1.调用Aware方法
进入方法中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader(); if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }
Aware是一个接口,官方的解释是一个超级标记接口,用于指示bean有资格通过回调样式方法由Spring容器通知特定框架对象,实际的方法签名由各个子接口确定。所以如果实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,则会调用相应的方法。
3.2.对类中某些特殊方法的调用,比如@PostConstruct
1
2
3
4
5
6
7
8
9
10
11
12
13public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
这里以InitDestroyAnnotationBeanPostProcessor为例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { //这个方法上面也见过了,收集@PostConstruct和@PreDestroy注解 LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { //利用反射进行方法调用 metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; }
3.3.调用InitMethod方法
指定初始化方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable { // 如果当前 bean 是 InitializingBean 的实例 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isTraceEnabled()) { logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> { ((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { // 直接调用afterPropertiesSet方法 ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null && bean.getClass() != NullBean.class) { String initMethodName = mbd.getInitMethodName(); if (StringUtils.hasLength(initMethodName) && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { // 调用init-method配置的方法 invokeCustomInitMethod(beanName, bean, mbd); } } }
3.4.调用postProcessAfterInitialization方法
1
2
3
4
5
6
7
8
9
10
11
12
13public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
初始化之后对bean的处理,这里以ApplicationListenerDetector为例,这里可以做为事件监听bean的探测器,将监听bean放到上下文的监听器集合中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22public Object postProcessAfterInitialization(Object bean, String beanName) { if (bean instanceof ApplicationListener) { // potentially not detected as a listener by getBeanNamesForType retrieval Boolean flag = this.singletonNames.get(beanName); if (Boolean.TRUE.equals(flag)) { // 事件监听的收集 this.applicationContext.addApplicationListener((ApplicationListener<?>) bean); } else if (Boolean.FALSE.equals(flag)) { if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) { // inner bean with other scope - can't reliably process events logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " + "but is not reachable for event multicasting by its containing ApplicationContext " + "because it does not have singleton scope. Only top-level listener beans are allowed " + "to be of non-singleton scope."); } this.singletonNames.remove(beanName); } } return bean; }
总结
- 调用applyMergedBeanDefinitionPostProcessor和populateBean完成DI
- 调用初始化方法的前后,会调用BeanPostProcessor的applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization方法对bean进行处理,我们可以依托于此对Spring进行二次开发。
最后
以上就是复杂棒棒糖最近收集整理的关于Spring源码之依赖注入、初始化分析前言一、注解的装配收集二、属性的依赖注入三、bean实例化后置处理总结的全部内容,更多相关Spring源码之依赖注入、初始化分析前言一、注解内容请搜索靠谱客的其他文章。
发表评论 取消回复