Spring 依赖注入的处理过程与 DependencyDescriptor 的说明

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学习资源】整理推荐

 

 


【Java面试题与答案】整理推荐

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值