populateBean分段1
在填充属性前,还会给InstantiationAwareBeanPostProcessor
的处理器处理,给他们机会让他们去修改bean
实例,这里也是扩展点。如果处理postProcessAfterInstantiation
方法会发false
,那就会停止属性填充,跳出循环并返回,说明可以控制是否要进行填充,但是spring
内部的处理器不会有处理,要处理还是要自定义去扩展处理器。
boolean continueWithPropertyPopulation = true;//是否让InstantiationAwareBeanPostProcessor继续执行
// 在填充前还可以用InstantiationAwareBeanPostProcessors来修改bean
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {//非合成的
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;//停止处理
break;
}
}
}
}
if (!continueWithPropertyPopulation) {//如果停止处理就返回
return;
}
populateBean分段2
获取自动装配模式,默认是NO
,如果有设置了,就会根据设置来进行装配。
//获取属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//获取自动装配模式,默认是no
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;
}
populateBean分段3
这里会进行InstantiationAwareBeanPostProcessor
处理器的postProcessProperties
处理,
//是否有InstantiationAwareBeanPostProcessors
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {//创建PropertyValues
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {//继续后置处理器处理
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
ConfigurationClassPostProcessor内部类ImportAwareBeanPostProcessor的postProcessProperties
这个就是前面如果配置类有Configuration
注解,会进行动态代理,会实现EnhancedConfiguration
接口,里面有个setBeanFactory
接口方法,会传入beanFactory
。
@Override
public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) {
// Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's
// postProcessProperties method attempts to autowire other configuration beans.
if (bean instanceof EnhancedConfiguration) {
((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory);
}
return pvs;
}
CommonAnnotationBeanPostProcessor的postProcessProperties
这里就处理我们前面applyMergedBeanDefinitionPostProcessors
处理注入注解元数据。
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}
InjectionMetadata的inject
遍历前面注册的InjectedElement
,然后进行注入。
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()) {
for (InjectedElement element : elementsToIterate) {
if (logger.isTraceEnabled()) {
logger.trace("Processing injected element of bean '" + beanName + "': " + element);
}
element.inject(target, beanName, pvs);
}
}
}
InjectedElement的inject
进行属性或者方法注入,但是方法注入前会判断是否已经有设置值了,有设置就不会注入,直接返回了。
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) {//属性注入
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
field.set(target, getResourceToInject(target, requestingBeanName));
}
else {
if (checkPropertySkipping(pvs)) {
return;
}
try {//方法注入
Method method = (Method) this.member;
ReflectionUtils.makeAccessible(method);
method.invoke(target, getResourceToInject(target, requestingBeanName));
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
checkPropertySkipping
判断是否要略过属性注入,如果是定义的时候给定值了就忽略。
protected boolean checkPropertySkipping(@Nullable PropertyValues pvs) {
Boolean skip = this.skip;
if (skip != null) {
return skip;
}
if (pvs == null) {
this.skip = false;
return false;
}
synchronized (pvs) {
skip = this.skip;
if (skip != null) {
return skip;
}
if (this.pd != null) {
if (pvs.contains(this.pd.getName())) {
// 给定了值了就忽略,直接返回
this.skip = true;
return true;
}
else if (pvs instanceof MutablePropertyValues) {//如果是可变的话,就注册到处理过的属性集合里
((MutablePropertyValues) pvs).registerProcessedProperty(this.pd.getName());
}
}
this.skip = false;
return false;
}
}
ResourceElement的getResourceToInject
getResourceToInject
是关键的方法,其实是InjectedElement
的抽象方法,子类有不同的实现类,比如ResourceElement
,EjbRefElement
,WebServiceRefElement
,当然我们就关注ResourceElement
啦,其他自己有兴趣可以看。
这个方法首先判断注释元数据有没有Lazy
注解,也就是懒加载,有的话会创建一个代理类,内部是用AOP
代理工厂做的,细节后面说,然后有个getTarget
代理方法,可以在需要时候调用获取。如果不是就直接getResource
。
@Override
protected Object getResourceToInject(Object target, @Nullable String requestingBeanName) {
return (this.lazyLookup ? buildLazyResourceProxy(this, requestingBeanName) :
getResource(this, requestingBeanName));
}
CommonAnnotationBeanPostProcessor的getResource
先判断jndi
的注入,然后才调用autowireResource
,我们一般就是autowireResource
。
protected Object getResource(LookupElement element, @Nullable String requestingBeanName)
throws NoSuchBeanDefinitionException {
if (StringUtils.hasLength(element.mappedName)) {
return this.jndiFactory.getBean(element.mappedName, element.lookupType);
}
if (this.alwaysUseJndiLookup) {
return this.jndiFactory.getBean(element.name, element.lookupType);
}
if (this.resourceFactory == null) {
throw new NoSuchBeanDefinitionException(element.lookupType,
"No resource factory configured - specify the 'resourceFactory' property");
}
return autowireResource(this.resourceFactory, element, requestingBeanName);
}
autowireResource
比较关键,我们后面再讲吧。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。