作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO
联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬
学习必须往深处挖,挖的越深,基础越扎实!
阶段1、深入多线程
阶段2、深入多线程设计模式
阶段3、深入juc源码解析
码哥源码部分
码哥讲源码-原理源码篇【2024年最新大厂关于线程池使用的场景题】
码哥讲源码-原理源码篇【揭秘join方法的唤醒本质上决定于jvm的底层析构函数】
码哥源码-原理源码篇【Doug Lea为什么要将成员变量赋值给局部变量后再操作?】
码哥讲源码【谁再说Spring不支持多线程事务,你给我抽他!】
打脸系列【020-3小时讲解MESI协议和volatile之间的关系,那些将x86下的验证结果当作最终结果的水货们请闭嘴】
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比较关键,我们后面再讲吧。
深入Java多线程与依赖注入原理:从源码到实践
628

被折叠的 条评论
为什么被折叠?



