文章目录
前言
上篇文章讲过了Spring实例化bean调用类的构造方法,但只是在堆内存中分配一块内存空间,但是类中的属性还没有注入到对象中,这篇文章着重讲解依赖注入的过程……
一、注解的装配收集
`// 这个方法主要完成对类中注解的收集工作
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);
}
}
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
循环遍历所有的MergedBeanDefinitionPostProcessor,主要有以下几种用于对注解的收集:
- AutowiredAnnotationBeanPostProcessor:处理@Autowired、@Value注解的收集
- CommonAnnotationBeanPostProcessor:处理@Resource注解的收集
- InitDestroyAnnotationBeanPostProcessor:处理@PostConstruct、@PreDestroy注解的收集
我们以AutowiredAnnotationBeanPostProcessor为例具体看看是怎么进行注解的收集工作的?
`public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
// 注解的信息封装到InjectionMetadata中
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}`
* 1
* 2
* 3
* 4
* 5
继续看findAutowiringMetadata方法
`private 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;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
接下里我们看,注解信息的主要封装过程buildAutowiringMetadata方法
`private InjectionMetadata buildAutowiringMetadata(final Class> clazz) {
// 如果类中没有相关注解,则返回空
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
// InjectedElement类型的集合
List elements = new ArrayList<>();
Class> targetClass = clazz;
do {
final List 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);
}`
* 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
我们在对属性进行依赖注入的时候,推荐使用@Resource注解,因为@Resource注解是JDK支持的,那么我们来看看Spring对@Resource的处理
`public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
// 处理@Resource注解的收集
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}`
* 1
* 2
* 3
* 4
* 5
* 6
经过跟踪源码,整体流程和对@Autowired的处理大同小异,但不同的是调用了父类的
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName)
这里又是做了些什么呢?
`public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
// 处理@PostConstruct、@PreDestroy注解的收集
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
metadata.checkConfigMembers(beanDefinition);
}`
* 1
* 2
* 3
* 4
* 5
继续看findLifecycleMetadata
`private 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;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
接着来看buildLifecycleMetadata方法
`private LifecycleMetadata buildLifecycleMetadata(final Class> clazz) {
// 如果没有注解则返回空
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
List initMethods = new ArrayList<>();
List destroyMethods = new ArrayList<>();
Class> targetClass = clazz;
do {
final List currInitMethods = new ArrayList<>();
final List 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
* 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
二、属性的依赖注入
`applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
|
>这个名字起的就非常有意思,填充bean,
populateBean(beanName, mbd, instanceWrapper);`
* 1
* 2
* 3
* 4
看看这个方法的具体操作
`protected 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);
}
}`
* 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
* 78
* 79
* 80
* 81
* 82
进入postProcessProperties方法,这个方法是一个钩子方法,直接看实现类
AutowiredAnnotationBeanPostProcessor.postProcessProperties
`public 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;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
进入到metadata.inject(bean, beanName, pvs);
`public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection checkedElements = this.checkedElements;
Collection 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);
}
}
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
进入到子类AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement的inject方法
`/**
* 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 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);
}
}`
* 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
方法的依赖注入与字段的类似,调用的子类AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement的inject方法,这里不多做赘述。
三、bean实例化后置处理
bean实例化并且IOC依赖注入完成之后,调用
`exposedObject = initializeBean(beanName, exposedObject, mbd);`
* 1
该方法都做了哪些事情呢
`protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction
下面分别从方法中注释的4点进行分析
3.1.调用Aware方法
进入方法中
`private 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);
}
}
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
Aware是一个接口,官方的解释是一个超级标记接口,用于指示bean有资格通过回调样式方法由Spring容器通知特定框架对象,实际的方法签名由各个子接口确定。所以如果实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware,则会调用相应的方法。
3.2.对类中某些特殊方法的调用,比如@PostConstruct
`public 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;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
这里以InitDestroyAnnotationBeanPostProcessor为例
`public 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;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
3.3.调用InitMethod方法
指定初始化方法
`protected 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
3.4.调用postProcessAfterInitialization方法
`public 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;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
初始化之后对bean的处理,这里以ApplicationListenerDetector为例,这里可以做为事件监听bean的探测器,将监听bean放到上下文的监听器集合中。
`public 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;
}`
* 1
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
* 10
* 11
* 12
* 13
* 14
* 15
* 16
* 17
* 18
* 19
* 20
* 21
总结
- 调用applyMergedBeanDefinitionPostProcessor和populateBean完成DI
- 调用初始化方法的前后,会调用BeanPostProcessor的applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization方法对bean进行处理,我们可以依托于此对Spring进行二次开发。