spring源码–10–IOC高级特性–autowiring实现原理
1、Spring IoC容器提供了2种方式 管理Bean的依赖关系
1.1、显式管理
通过BeanDefinition的属性值和构造方法实现Bean依赖关系管理。
1.2、autowiring(自动装配)
不需要对Bean属性的依赖关系做显式的声明,只需要在配置好autowiring属性,IoC容器会自动使用反射查找属性的类型和名称,然后基于属性的类型或者名称来自动匹配容器中管理的Bean,从而自动地完成依赖注入。
对Bean的自动装配发生在容器对Bean依赖注入的过程中。具体在AbstractAutoWireCapableBeanFactory.populateBean()方法中,我们通过源码分析autowiring的实现原理。
2、自动装配 源码
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* 使用 RootBeanDefinition的属性值 填充给定 BeanWrapper 中的bean实例。
*
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw BeanWrapper with bean instance
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
.
.
.
// 对autowire自动装配的处理,根据Bean名称自动装配注入
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
// 根据Bean类型自动装配注入
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
.
.
.
}
//根据Bean名称自动装配注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//对Bean对象中非简单属性(不是简单继承的对象,如原始类型,字符串,URL等//都是简单属性)进行处理
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
//如果Spring IOC容器中包含指定名称的Bean
if (containsBean(propertyName)) {
//调用getBean方法向IoC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入
Object bean = getBean(propertyName);
//为指定名称的属性赋予属性值
pvs.add(propertyName, bean);
//指定名称属性注册依赖Bean名称,进行属性依赖注入
//真正依赖注入的地方
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
// 根据Bean类型自动装配注入
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取用户定义的类型转换器
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//存放解析的要注入的属性
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
//对Bean对象中非简单属性(不是简单继承的对象,如8中原始类型,字符URL等都是简单属性)进行处理
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
//获取指定属性名称的属性描述器
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
//不对Object类型的属性进行autowiring自动依赖注入
if (Object.class != pd.getPropertyType()) {
//获取属性的setter方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
//检查指定类型是否可以被转换为目标对象的类型
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
//创建一个要被注入的依赖描述
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//根据容器的Bean定义解析依赖关系,返回所有要被注入的Bean对象
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
//为属性赋值所引用的对象
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
//指定名称属性注册依赖Bean名称,进行属性依赖注入
//真正依赖注入的地方
registerDependentBean(autowiredBeanName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
//释放已自动注入的属性
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
}
3、DefaultSingletonBeanRegistry.registerDependentBean 源码
真正实现属性注入的是DefaultSingletonBeanRegistry.registerDependentBean方法
3.1、源码
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
//为指定的Bean注入依赖的Bean
public void registerDependentBean(String beanName, String dependentBeanName) {
//处理Bean名称,将别名转换为规范的Bean名称
String canonicalName = canonicalName(beanName);
//多线程同步,保证容器内数据的一致性
//先从容器中:bean名称-->全部依赖Bean名称集合 查找给定名称Bean的依赖Bean
synchronized (this.dependentBeanMap) {
//获取给定名称Bean的所有依赖Bean名称
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
// 添加不成功就结束,成功就继续走下去
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
//从容器中:bean名称-->指定名称Bean的依赖Bean集合中 查找给定名称
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
//向容器中:bean名称-->指定Bean的依赖Bean名称集合添加Bean的依赖信息
//即,将Bean所依赖的Bean添加到容器的集合中
dependenciesForBean.add(canonicalName);
}
}
}
4、总结
通过对autowiring的源码分析,我们可以看出,autowiring的实现过程:
1. 对Bean的属性迭代调用getBean方法,完成依赖Bean的初始化和依赖注入。
2. 将依赖Bean的属性引用设置到被依赖的Bean属性上。
3. 将依赖Bean的名称和被依赖Bean的名称存储在IoC容器的集合中。
4.1、缺点
- Bean的依赖关系在配置文件中无法很清楚地看出来,对于维护造成一定困难。
- 由于自动依赖注入是Spring容器自动执行的,容器是不会智能判断的,如果配置不当,将会带来无法预料的后果
4.2、优点
简化开发配置