Spring 依赖注入处理的代码入口在 DefaultListableBeanFactory#resolveDependency() 方法。
该方法第一个参数 DependencyDescriptor descriptor 继承自 InjectionPoint,是这次依赖注入的描述,类里的信息说明如下:
//依赖所在的声明类
private final Class<?> declaringClass;
//如果依赖是成员方法的某个参数,则这里记录该成员方法的名称
private String methodName;
//如果包装的是成员方法的某个参数,则这里记录该参数的类型
private Class<?>[] parameterTypes;
//如果包装的是成员方法的某个参数,则这里记录该参数在该函数参数列表中的索引
private int parameterIndex;
//成员属性的名称
private String fieldName;
//是否必要依赖
private final boolean required;
//是否需要饥饿加载
private final boolean eager;
//嵌套级别
private int nestingLevel = 1;
//依赖的包含者类,通常和声明类是同一个
private Class<?> containingClass;
结合测试代码看一下:
User 类和 Friend 类,User 中注入 Friend 对象
@Component
public class User {
@Autowired
private Friend friend;
@Override
public String toString() {
return "User{" +
"friend=" + friend +
'}';
}
}
@Component
public class Friend {
private String name = "friend";
@Override
public String toString() {
return "Friend{" +
"name='" + name + ''' +
'}';
}
}
测试代码
/**
* 测试 Bean 依赖注入的处理,进行源码调试
*
* @author ConstXiong
*/
public class Test {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("constxiong");
User user = context.getBean(User.class);
System.out.println(user);
}
}
DefaultListableBeanFactory#resolveDependency() 方法的逻辑
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
//如需,进行 Optional 包装处理
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
//ObjectFactory 或 ObjectProvider 延迟加载的处理
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// Jsr330 规范相关处理
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
//处理依赖注入逻辑
else {
//getAutowireCandidateResolver() 自动绑定处理器
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
以下注解的依赖注入的处理在 AutowiredAnnotationBeanPostProcessor 类中
- @Autowired
- @Value
- @Inject 会根据是否 jar 包是否存在该类进行判断加载
以下注解的依赖注入的处理在 CommonAnnotationBeanPostProcessor 类中
- @Resource
- @PostConstruct
- @PreDestroy
- @WebServiceRef
- @EJB
- AbstractApplicationContext#registerBeanPostProcessors 方法,在 ApplicationContext 启动时,查找和注册 BeanPostProcessor
- AbstractAutowireCapableBeanFactory#doCreateBean 创建 bean 的时候,doCreateBean 方法调用 MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition 方法
- AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 均是 MergedBeanDefinitionPostProcessor 接口的实现类,借助 findAutowiringMetadata 方法查找 InjectionMetadata 注入元信息
- AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor 均是 InstantiationAwareBeanPostProcessor 实现类;AbstractAutowireCapableBeanFactory#populateBean 方法中调用了 AutowiredAnnotationBeanPostProcessor 或 CommonAnnotationBeanPostProcessor#postProcessProperties 完成 InjectionMetadata#inject 属性注入
完整代码:018-spring-resolve-dependency
【Java学习资源】整理推荐
- 自定义 Bean 作用域
- Bean 的作用域
- maven 集成 tomcat 以 jar 的方式打包 web 应用
- Spring 依赖注入与依赖查找来源的区别
- Spring 依赖注入的处理过程与 DependencyDescriptor 的说明
- Spring 各种 Aware 接口回调注入
- Spring Bean 生命周期内的 Exception 复现
- Spring 内建 Bean
- Spring Bean 的别名
- Spring Bean 未指定名称的命名规则
- Bean 何时被 GC
- Spring Bean 延迟加载
- ObjectFactory 与 BeanFactory 的区别
- Bean 销毁的方式与顺序
- Bean 初始化的方式与顺序
- Bean 的实例化方式
- Bean的注册方式
- 什么是 BeanDefinition?
- Spring IoC 容器启动时做了什么?
- BeanFactory 与 FactoryBean 的区别
- BeanFactory 与 ApplicationContext 的区别
- Spring IoC 依赖注入的实现方式
- Spring IoC 依赖注入(支持哪些数据类型?)
- Spring bean 依赖查找
- Spring-IoC
- Spring 的核心特性