5、Spring源码-依赖注入(上)
一、Spring中到底有几种依赖注入的方式?
首先分两种:
手动注入
自动注入
1.1、手动注入
在XML中定义Bean时,就是手动注入,因为是手动给某个属性指定了值。
<!-- 这种底层是通过set方法进行注入 --> <bean name="userService" class="com.zender.service.UserService"> <property name="orderService" ref="orderService"/> </bean>
<!-- 这种底层是通过构造方法进行注入 --> <bean name="userService" class="com.zender.service.UserService"> <constructor-arg index="0" ref="orderService"/> </bean>
所以手动注入的底层也就是分为两种:
set方法注入
构造方法注入
1.2、自动注入
自动注入又分为两种:
XML的autowire自动注入
<bean id="userService" class="com.zender.service.UserService" autowire="byType"/>
这么写,表示Spring会自动的给userService中所有的属性自动赋值(不需要这个属性上有@Autowired注解,但需要这个属性有对应的set方法)。
在创建Bean的过程中,在填充属性时,Spring会去解析当前类,把当前类的所有方法都解析出来,Spring会去解析每个方法得到对应的PropertyDescriptor(属性描述器)对象,PropertyDescriptor(属性描述器)中有几个属性:
name:这个name并不是方法的名字,而是拿方法名字进过处理后的名字。
如果方法名字以“get”开头,比如“getXXX”,那么name=XXX。
如果方法名字以“is”开头,比如“isXXX”,那么name=XXX。
如果方法名字以“set”开头,比如“setXXX”,那么name=XXX。
readMethodRef:表示get方法的Method对象的引用。
readMethodName:表示get方法的名字。
writeMethodRef:表示set方法的Method对象的引用。
writeMethodName:表示set方法的名字。
propertyTypeRef:如果有get方法那么对应的就是返回值的类型,如果是set方法那么对应的就是set方法中唯一参数的类型。
get方法的定义是: 方法参数个数为0个,并且方法名字以"get"开头 或者 方法名字以"is"开头并且方法的返回类型为boolean。
set方法的定义是:方法参数个数为1个,并且 方法名字以"set"开头并且方法返回类型为void。
所以,Spring在通过byName的自动填充属性时流程是:
找到所有set方法所对应的XXX部分的名字。
根据XXX部分的名字去获取bean,进行属性填充。
Spring在通过byType的自动填充属性时流程是:
获取到set方法中的唯一参数的参数类型,并且根据该类型去容器中获取bean,进行属性填充。
如果找到多个,会报错。
@Autowired注解的自动注入
@Autowired注解相当于XML中的autowire属性的注解方式的替代。
从本质上讲,@Autowired注解提供了与autowire相同的功能,但是拥有更细粒度的控制和更广泛的适用性。
XML中的autowire控制的是整个bean的所有属性,而@Autowired注解是直接写在某个属性、某个set方法、某个构造方法上的。
举个例子,如果一个类有多个构造方法,那么如果用XML的autowire=constructor,你无法控制到底用哪个构造方法,而你可以用@Autowired注解来直接指定你想用哪个构造方法。
同时,用@Autowired注解,还可以控制,哪些属性想被自动注入,哪些属性不想,这也是细粒度的控制。
但是@Autowired无法区分byType和byName,@Autowired是先byType,如果找到多个则byName。
@Autowired注解可以写在:
属性上:先根据属性类型去找Bean,如果找到多个再根据属性名确定。
构造方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定。
set方法上:先根据方法参数类型去找Bean,如果找到多个再根据参数名确定。
二、寻找注入点
想要支持依赖注入,需要先找到需要注入点,缓存起来。
在创建一个Bean的过程中,Spring会利用AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()找出注入点并缓存。
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//寻找切入点并缓存
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}2.1、findAutowiringMetadata()
//获取给定类的@Autowired注解信息
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
// 第一次进来metadata为空
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);
//将得到的给定类@Autowired注解信息存储在容器缓存中
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}2.2、buildAutowiringMetadata()
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>();
Class<?> targetClass = clazz;
//遍历当前类及其所有基类,解析全部字段
do {
final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>();
//利用JDK反射机制遍历targetClass中的所有字段,获取字段上的注解信息
ReflectionUtils.doWithLocalFields(targetClass, field -> {
//获取给定字段上的注解,是否存在@Autowired、@Value、@inject中的一个
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
//如果给定字段是静态的(static),不会进行注入
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//判断注解的required属性值是否有效
boolean required = determineRequiredStatus(ann);
//构造注入点,添加在返回的集合中
currElements.add(new AutowiredFieldElement(field, required));
}
});
//利用JDK反射机制获取给定类中所有的声明方法,获取方法上的注解信息
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
//方法可能是个桥接方法,需要找到原方法进行解析
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
//获取给定方法上的所有注解
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
//如果方法是静态的,则直接遍历下一个方法
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
//如果方法的参数列表为空
if (method.getParameterCount() == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
//判断注解的required属性值是否有效
boolean required = determineRequiredStatus(ann);
//获取当前方法的属性描述符,即方法是可读的(readable)getter方法,还是可写的(writeable)setter方法
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
//构造注入点,添加在返回的集合中
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
//将当前类的注入点存放到集合中
elements.addAll(0, currElements);
//获取给定类的父类
targetClass = targetClass.getSuperclass();
}
//如果给定类有基类,并且基类不是Object,则递归获取其基类的元信息
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}2.3、static的字段或方法为什么不支持注入
@Component
@Scope("prototype")
public class OrderService {
}
@Component
@Scope("prototype")
public class UserService {
@Autowired
private static OrderService orderService;
public void test() {
System.out.println("test123");
}
}UserService和OrderService都是原型Bean,假设Spring支持static字段进行自动注入,那么现在调用两次getBean()
UserService userService1 = context.getBean("userService");
UserService userService2 = context.getBean("userService");问此时,userService1的orderService值是什么?还是它自己注入的值吗?
答案是不是,一旦userService2创建好了之后,static orderService字段的值就发生了修改了,从而出现bug。
三、注入点(方法/字段)进行注入
//真正创建Bean的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
//准备封装被创建的Bean对象
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//有可能再Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入),缓存中移除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建Bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
//获取实例化对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
//调用PostProcessor(BeanDefinition的后置处理器)
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
//向容器中缓存单例模式的Bean对象,以防循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//这里是一个匿名内部类,为了防止循环依赖,尽早持有对象的引用(也就是添加到三级缓存)
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
//Bean对象的初始化,依赖注入在此触发
//这个exposedObject在初始化完成之后返回作为依赖注入完成后的Bean
Object exposedObject = bean;
try {
//将Bean实例对象属性填充
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean对象
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
//获取指定名称的已注册的单例模式Bean对象
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
//根据名称获取的已注册的Bean和正在实例化的Bean是同一个
if (exposedObject == bean) {
//当前实例化的Bean初始化完成
exposedObject = earlySingletonReference;
}
//当前Bean依赖其他Bean,并且当发生循环引用时不允许新创建实例对象
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
//获取当前Bean所依赖的其他Bean
for (String dependentBean : dependentBeans) {
//对依赖Bean进行类型检查
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//注册Bean销毁时的相关操作
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}依赖注入的主要逻辑在AbstractAutowireCapableBeanFactory#populateBean()中
//获取容器在解析Bean定义资源时为BeanDefiniton中设置的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//对依赖注入处理,首先处理autowire自动装配的依赖注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
//MutablePropertyValues是PropertyValues具体的实现类
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
//根据Bean名称进行autowire自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
//根据Bean类型进行autowire自动装配处理
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
//检查后处理器是否已经准备好了
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//如果是@Autowired注解/@value注解,会调用AutowiredAnnotationAwareBeanPostProcessor.postProcessPropertyValues方法
//如果是@resource注解,会调用CommonAnnotationAwareBeanPostProcessor.postProcessPropertyValues方法去处理。
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//处理属性
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//为BeanDefiniton中设置的属性,进行注入赋值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}3.1、autowireByName()方法
//根据名称对属性进行自动依赖注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//获取Bean中能进行自动注入的属性名
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
// 遍历每个属性名,并去获取bean对象,并设置到pvs中
for (String propertyName : propertyNames) {
//如果Spring IOC容器中包含指定名称的Bean
if (containsBean(propertyName)) {
//调用getBean方法向IOC容器索取指定名称的Bean实例,迭代触发属性的初始化和依赖注入
Object bean = getBean(propertyName);
//为指定名称的属性赋予属性值
pvs.add(propertyName, bean);
//记录propertyName(属性名)是被那个beanName所依赖的
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("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");
}
}
}
}unsatisfiedNonSimpleProperties(),该方法去获取Bean中能进行自动注入的属性名:
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
PropertyValues pvs = mbd.getPropertyValues();
//属性描述器,只能拿到有对应set/get方法的属性
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
//什么样的属性能进行自动注入?
//1、该属性有对应set方法
//2、没有在ignoredDependencyTypes中
//3、如果属性对应的set是实现某个接口中所定义的,并且接口也没有在ignoredDependencyTypes中
//4、属性类型不是简单类型,比如int,Integer,int[]。
for (PropertyDescriptor pd : pds) {
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}什么样的属性能进行自动注入?
该属性有对应set方法。
没有在ignoredDependencyTypes中。
如果属性对应的set是实现某个接口中所定义的,并且接口也没有在ignoredDependencyTypes中。
属性类型不是简单类型,比如int,Integer,int[]。
3.2、autowireByType()方法
//根据类型对属性进行自动依赖注入
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 = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());
//创建一个要被注入的依赖描述
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) {
//记录propertyName(属性名)是被那些bean所依赖的
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("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);
}
}
}registerDependentBean()方法
//为指定的Bean查找依赖的Bean
//并放入dependentBeanMap(某个bean被哪些Bean)和dependenciesForBeanMap(某个bean依赖了哪些Bean)中
public void registerDependentBean(String beanName, String dependentBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
//处理Bean名称,将别名转换为规范的Bean名称
String canonicalName = canonicalName(beanName);
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
}
// No entry yet -> fully synchronized manipulation of the dependentBeans Set
//多线程同步,保证容器内数据的一致性
//处理某个bean被哪些Bean依赖了
synchronized (this.dependentBeanMap) {
//获取给定名称Bean的所有依赖Bean
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
//为Bean设置被依赖Bean信息
dependentBeans = new LinkedHashSet<>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
//为Bean设置被依赖Bean信息
dependentBeans.add(dependentBeanName);
}
//处理某个bean依赖了哪些Bean了
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
//为Bean设置依赖了Bean信息
dependenciesForBean.add(canonicalName);
}
}四、处理注解
//检查后处理器是否已经准备好了
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//是否需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//如果是@Autowired注解/@value注解,会调用AutowiredAnnotationAwareBeanPostProcessor.postProcessPropertyValues方法
//如果是@resource注解,会调用CommonAnnotationAwareBeanPostProcessor.postProcessPropertyValues方法去处理。
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//处理属性
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//为BeanDefiniton中设置的属性,进行注入赋值
applyPropertyValues(beanName, mbd, bw, pvs);
}如果是@Autowired注解/@value注解,会调用AutowiredAnnotationAwareBeanPostProcessor#postProcessPropertyValues()方法处理。
//处理类中的属性
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
//获取指定类中autowire相关注解的元信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
//对Bean的属性进行自动注入
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;
}如果是@resource注解,会调用CommonAnnotationAwareBeanPostProcessor#postProcessPropertyValues()方法去处理。
//对字段进行注入
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//获取注入元素对象
Field field = (Field) this.member;
Object value;
//如果当前对象在容器中被缓存
if (this.cached) {
//根据Bean名称解析缓存中的字段值
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 {
//根据容器中Bean定义,解析指定的依赖关系,获取依赖对象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
//线程同步,确保容器中数据一致性
synchronized (this) {
//如果当前对象没有被容器缓存
if (!this.cached) {
//获取到了当前对象的依赖对象,并且required属性为true
if (value != null || this.required) {
this.cachedFieldValue = desc;
//为指定Bean注册依赖Bean
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
//如果容器中有指定名称的Bean对象
if (beanFactory.containsBean(autowiredBeanName)) {
//依赖对象类型和字段类型匹配,默认按类型注入
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
//创建一个依赖对象的引用,同时缓存
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
//如果获取的依赖关系为null,且获取required属性为false
else {
//将字段值的缓存设置为null
this.cachedFieldValue = null;
}
//容器已经对当前字段的值缓存
this.cached = true;
}
}
}
//如果字段依赖值不为null
if (value != null) {
//显式使用JDK的反射机制,设置自动的访问控制权限为允许访问
ReflectionUtils.makeAccessible(field);
//为Bean对象的字段设置值
field.set(bean, value);
}
}4.1、注入点进行注入
public 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()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}属性
//对字段进行注入
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//获取注入元素对象
Field field = (Field) this.member;
Object value;
//如果当前对象在容器中被缓存
if (this.cached) {
//根据Bean名称解析缓存中的字段值
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 {
//根据容器中Bean定义,解析指定的依赖关系,获取依赖对象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
//线程同步,确保容器中数据一致性
synchronized (this) {
//如果当前对象没有被容器缓存
if (!this.cached) {
//获取到了当前对象的依赖对象,并且required属性为true
if (value != null || this.required) {
this.cachedFieldValue = desc;
//为指定Bean注册依赖Bean
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
//如果容器中有指定名称的Bean对象
if (beanFactory.containsBean(autowiredBeanName)) {
//依赖对象类型和字段类型匹配,默认按类型注入
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
//创建一个依赖对象的引用,同时缓存
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
}
//如果获取的依赖关系为null,且获取required属性为false
else {
//将字段值的缓存设置为null
this.cachedFieldValue = null;
}
//容器已经对当前字段的值缓存
this.cached = true;
}
}
}
//如果字段依赖值不为null
if (value != null) {
//显式使用JDK的反射机制,设置自动的访问控制权限为允许访问
ReflectionUtils.makeAccessible(field);
//为Bean对象的字段设置值
field.set(bean, value);
}
}方法
//对方法进行注入
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
//如果属性被显式设置为skip,则不进行注入
if (checkPropertySkipping(pvs)) {
return;
}
//获取注入元素对象
Method method = (Method) this.member;
Object[] arguments;
//如果容器对当前方法缓存
if (this.cached) {
// Shortcut for avoiding synchronization...
//获取缓存中指定Bean名称的方法参数
arguments = resolveCachedArguments(beanName);
}
//如果没有缓存
else {
//获取方法的参数列表
Class<?>[] paramTypes = method.getParameterTypes();
//创建一个存放方法参数的数组
arguments = new Object[paramTypes.length];
DependencyDescriptor[] descriptors = new DependencyDescriptor[paramTypes.length];
Set<String> autowiredBeans = new LinkedHashSet<>(paramTypes.length);
Assert.state(beanFactory != null, "No BeanFactory available");
//获取容器的类型转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
for (int i = 0; i < arguments.length; i++) {
//创建方法参数对象
MethodParameter methodParam = new MethodParameter(method, i);
DependencyDescriptor currDesc = new DependencyDescriptor(methodParam, this.required);
currDesc.setContainingClass(bean.getClass());
//解析方法的输入参数,为方法参数创建依赖描述符
descriptors[i] = currDesc;
try {
Object arg = beanFactory.resolveDependency(currDesc, beanName, autowiredBeans, typeConverter);
if (arg == null && !this.required) {
arguments = null;
break;
}
//根据容器中Bean定义解析依赖关系,获取方法参数依赖对象
arguments[i] = arg;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(methodParam), ex);
}
}
//线程同步,以确保容器中数据一致性
synchronized (this) {
//如果当前方法没有被容器缓存
if (!this.cached) {
//如果方法的参数列表不为空
if (arguments != null) {
//为容器中缓存方法参数的对象赋值
Object[] cachedMethodArguments = new Object[paramTypes.length];
for (int i = 0; i < arguments.length; i++) {
cachedMethodArguments[i] = descriptors[i];
}
//为指定Bean注册依赖Bean
registerDependentBeans(beanName, autowiredBeans);
//如果依赖对象集合大小等于方法参数个数
if (autowiredBeans.size() == paramTypes.length) {
Iterator<String> it = autowiredBeans.iterator();
//为方法参数设置依赖对象
for (int i = 0; i < paramTypes.length; i++) {
String autowiredBeanName = it.next();
//如果容器中存在指定名称的Bean对象
if (beanFactory.containsBean(autowiredBeanName)) {
//如果参数类型和依赖对象类型匹配
if (beanFactory.isTypeMatch(autowiredBeanName, paramTypes[i])) {
//创建一个依赖对象的引用,复制给方法相应的参
cachedMethodArguments[i] = new ShortcutDependencyDescriptor(
descriptors[i], autowiredBeanName, paramTypes[i]);
}
}
}
}
this.cachedMethodArguments = cachedMethodArguments;
}
//如果方法参数列表为null,则设置容器对该方法参数的缓存为null
else {
this.cachedMethodArguments = null;
}
//设置容器已经对该方法缓存
this.cached = true;
}
}
}
//如果方法参数依赖对象不为null
if (arguments != null) {
try {
//使用JDK的反射机制,显式设置方法的访问控制权限为允许访问
ReflectionUtils.makeAccessible(method);
//调用Bean的指定方法
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex){
throw ex.getTargetException();
}
}
}版权声明
非特殊说明,本文由Zender原创或收集发布,欢迎转载。
ZENDER
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。