共计 28540 个字符,预计需要花费 72 分钟才能阅读完成。
本文出处 Spring Bean 如何初始化的 转载请阐明出处
做 Java 都有很多年了,始终有一个纳闷:Spring 如何初始化 bean,怎么调用反射实例化对象的,本人入手来解除这个纳闷。
过来我认为 spring bean 对象实例化始终都是由 BeanPostProcessor
接口实现类去做的,我就是不晓得具体那个实现类,上面就去验证下这个猜测。
三级缓存
为什么面试官特地喜爱问创立 bean 的三级缓存,次要是因为 bean 创立都是随同着三级缓存之间的转换实现的,对象不同状态别离存在不同缓存中,上面我会在剖析代码时,顺便反对对象如何在缓存中流转的。
先理解下 spring 三级缓存。
/** 一级缓存 用于寄存齐全能够应用单例 bean,也就是初始化实现并且注入所有依赖 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 二级缓存 过早裸露单例对象,此时 bean 刚刚实现初始化,未实现属性注入和执行 init 办法 */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** 三级缓存 装载创立 bean 的工厂对象 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16)
三级缓存次要作用:创建对象 ObjectFactory 首先放入三级换缓存中,当调用 getObject 创立实例时,会将创立好对象退出二级缓存中,并且删除三级中缓存,当对象曾经实现初始化办法和属性注入,再将缓存增加到一级缓存中,并且删除二级缓存。
doGetBean
从源头开始找,所有 spring bean 初始化都是由 AbstractBeanFactory.doGetBean
办法实现的。上面我将源码减除臃肿局部,贴出来。
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//name 前缀解决 beanFactory beanName 带有 & 结尾
String beanName = transformedBeanName(name);
Object beanInstance;
// 从三级缓存去取 bean,三级中都没有则返回 null,阐明对象还没有创立
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) { // 如果缓存中 bean 是 FactoryBean 实例,要通过接口获取到理论 bean
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 判断 bean 对象标记是否正在创立中,如果正在创立中则不应该继续下去,呈现依赖循环就会呈现这个谬误
if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
// 查看父容器是否存在,尝试从父容器中获取
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) { // 缓存中标记 beanName 正在被创立
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) { //bean 中 @DependsOn 信息,用于标记 bean 之间初始化程序,优先创立 @DependsOn 中 bean
for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between'" + beanName + "'and'" + dep + "'");
}
registerDependentBean(dep, beanName);
try {getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'"+ beanName +"' depends on missing bean '"+ dep +"'", ex);
}
}
}
// 创立单例对象
if (mbd.isSingleton()) { // 重点就在这里实例化对象,getSingleton 就是在这里将创立实现对象退出到一级缓存中
sharedInstance = getSingleton(beanName, () -> {
try {return createBean(beanName, mbd, args);
}
catch (BeansException ex)
destroySingleton(beanName);
throw ex;
}
});
// 如果生成 bean 是 FactoryBean,再获取真正的对象
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 作用域 = prototype,因为不会放入缓存中,每次获取都要从新创立
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else { // session request 这些作用域,由作用域容器去治理这些对象
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
Scope scope = this.scopes.get(scopeName);
if (scope == null) {throw new IllegalStateException("No Scope registered for scope name'" + scopeName + "'");
}
try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);
try {return createBean(beanName, mbd, args);
}
finally {afterPrototypeCreation(beanName);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {beanCreation.end();
}
}
// 返回初始化胜利的对象,一个对象初始化就这样实现的了
return adaptBeanInstance(name, beanInstance, requiredType);
}
大略总结一下下面代码流程:
- 先从三级缓存中获取,如果缓存中都没有。再去判断是否存在父容器,从父容器中获取。没有正式进入 bean 初始化流程,先依据 beanName 获取到 RootBeanDefinition,bean 类元信息、先解决 dependsOn 中 bean,保障 bean 依赖的创立程序,上面会阐明
org.springframework.context.annotation.@DependsOn
这个注解。下一步依照不同 scope 进行 bean 对象初始化。初始化流程就是这样,咱们将眼光放在单例 bean 如何实例化,集中关注AbstractAutowireCapableBeanFactory.createBean
获取注册一个单例对象
@DependsOn
注解意思是实例化某个对象依赖于某一个实例化,然而不须要持有这个实例对象。比方 bean A 上 须要依赖 bean b 能力实例化,然而 bean b 不须要作为他的属性,经常用于不同实例实例化程序标记。
看下 getSingleton 办法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) { // 标记 bean 是否在销毁
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction" +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();
}
try {singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) { }
catch (BeanCreationException ex) {throw ex;}
finally {if (recordSuppressedExceptions) {this.suppressedExceptions = null;}
afterSingletonCreation(beanName);
}
if (newSingleton) {addSingleton(beanName, singletonObject); // 就是在这里删除二三级缓存,提交到一级缓存
}
}
return singletonObject;
}
}
protected void addSingleton(String beanName, Object singletonObject) {synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
增加到一级缓存则阐明 bean 曾经实现实例化,能够失常应用了。上面看下如何进行实例化和属性注入的。
createBean
上面进入AbstractAutowireCapableBeanFactory.createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 克隆一份 mbd => mbdToUse
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 通过 BeanPostProcessors 加强返回一个代理对象,这个生成 AOP 的代理对象,应用多个 BeanPostProcessors 来解决
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {return bean;}
}
catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// bean 对象实例化就这里实现
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {throw ex;}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
这里逻辑就比较简单了,克隆一份 RootBeanDefinition 用于初始化对象,resolveBeforeInstantiation 次要用于初始化代理对象状况,次要应用 BeanPostProcessor 子类 InstantiationAwareBeanPostProcessor 实现办法去实现对象初始化,并且在实例化胜利后在调用后置办法进行对象依赖注入,这里能够看见此办法返回对象间接跳出办法栈,这里能够看出单例和代理对象还是有区别的。单例对象初始化就在 doCreateBean 实现了
doCreateBean
上面就是 AbstractAutowireCapableBeanFactory.doCreateBean
十分靠近对象如何实例化的了
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args); // 这个就是实例化办法
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}
// 应用 BeanDefinitionPostProcessors 对合并 bean 进行实例化
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;
}
}
// 这里就须要用到下面说的三级缓存常识了
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName)); // 是否放入第三级缓存中
if (earlySingletonExposure) {if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean'" + beanName +
"'to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // 将曾经实例化的对象退出到第三级缓存 singletonFactories
}
// Initialize the bean instance.
Object exposedObject = bean;
try {populateBean(beanName, mbd, instanceWrapper); // 对属性进入注入,上面会具体分析的
exposedObject = initializeBean(beanName, exposedObject, mbd); // 执行初始化办法,或者注入 Aware 接口 bean
}
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);
}
}
// 上面代码省略
// 次要就是对设置了 DisposableBean 接口销毁钩子办法解决
}
这里代码次要分成三局部
- 初始化实例,创建对象实现,并且增加到 3 级缓存。第 3 级缓存经常用于存储代理对象,因为有些类须要动静代理办法,须要生成代理对象,会委派给第三级缓存办法 ObjectFactroy 去实现的,一般对象如果不须要会间接返回。
- 对实例化 bean 进行属性注入
- 执行初始化办法,DisposableBean 接口退出到 disposableBeans 容器中
instantiateBean
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {// 有实现 Supplier 接口,由 instanceSupplier.get() 办法创立实例
return obtainFromSupplier(instanceSupplier, beanName);
}
//factoryName 应用工厂模式创立 bean,调用工厂办法去创立,这个反对静态方法和 factoryBean.invoke
if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false; // 标记构造函数是否须要参数
boolean autowireNecessary = false; // 标记构造方法的参数是否应用注入形式
if (args == null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {if (autowireNecessary) {
// 应用构造函数注入形式实例化
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 实例化对象
return instantiateBean(beanName, mbd);
}
}
// 获取结构函数参数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
实例化办法 instantiateBean 最终会调用 SimpleInstantiationStrategy.instantiate 进行实例化
instantiate
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {constructorToUse = clazz.getDeclaredConstructor(); // 获取构造函数
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse); // 调用构造函数进行实例化
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
instantiateClass
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse); // 调用结构器进行初始化
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
这里要留神下先判断 bean 是否有办法重写的,没有则应用反射生成的结构器,有就应用 gclib 形式创立代理对象,具体实现形式就在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate
,有趣味同学能够去学习下。
到此一个简略 bean 实例化实现了。
注入
上面进入 IOC 另一个特点,bean 注入,先从 AbstractAutowireCapableBeanFactory.populateBean
办法开始
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 通过 InstantiationAwareBeanPostProcessors.postProcessAfterInstantiation 如果返回 true,指标实例外部的返回值会被 populate,否则 populate 这个过程会被忽视
// 翻译说如果返回 true 能够执行字段注入 真的 6666 啊
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 获取注入形式散布有 4 种
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;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 依赖形式,模式都是没有类型查看,这种依赖形式个别都是 xml 配置用得比拟多,没有配置这里都是返回 false
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); /
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); // 获取注解标注须要注入办法或者是字段,并且进行注入
if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {return;}
}
pvs = pvsToUse;
}
}
if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);
}
}
小知识点:
AutowireCapableBeanFactory.AUTOWIRE_NO 表明不会对以后 Bean 进行外部类的注入,惯例应用 @Autowire、@Resource 都是这类型
剩下三种都是通过 xml 或者 AutowireCapableBeanFactory.autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) 进行设置 autowireMode。
依据下面代码能够晓得主流程 bean 注入都是由 InstantiationAwareBeanPostProcessor 进行解决的, 简略阐明接口办法
办法 | 形容 |
---|---|
postProcessBeforeInitialization | 办法是最 先执行的办法,它在指标对象实例化之前调用,该办法的返回值类型是 Object,咱们能够返回任何类型的值。因为这个时候指标对象还未实例化,所以这个返回值能够用来代替本来该生成的指标对象的实例(比方代理对象)。如果该办法的返回值代替本来该生成的指标对象,后续只有 postProcessAfterInitialization 办法会调用,其它办法不再调用;否则依照失常的流程走 |
postProcessAfterInitialization | 办法在指标对象实例化之后调用,这个时候对象曾经被实例化,然而该实例的属性还未被设置,都是 null。因为它的返回值是决定要不要调用 postProcessPropertyValues 办法的其中一个因素(因为还有一个因素是 mbd.getDependencyCheck());如果该办法返回 false, 并且不须要 check,那么 postProcessPropertyValues 就会被疏忽不执行;如果返回 true,postProcessPropertyValues 就会被执行 |
postProcessPropertyValues | 对 bean 属性值赋值后调用,对属性值的批改。如果 postProcessAfterInstantiation 办法返回 false,该办法可能不会被调用。能够在该办法内对属性值进行批改 |
postProcessProperties | Bean 属性赋值就是调用这个办法的 |
InstantiationAwareBeanPostProcessor 接口实现类次要分 3 个
- ConfigurationClassPostProcessor:看类名就晓得解决 @Configuration 实例化,并没有属性注入逻辑,不详讲略过。
- CommonAnnotationBeanPostProcessor:这个类就是实现 bean 注入,然而是实现 JSR-250 注解、@Resource,@EJB、@WebServiceRef,@WebServiceContext,@PostConstrusct、@PreDestory 这些注解实现。
- AutowiredAnnotationBeanPostProcessor:实现 @Autowired、@Value 注入, 并且反对 JSR-330’s @Inject, 次要剖析这个类就能够晓得 bean 注入的。
AutowiredAnnotationBeanPostProcessor 剖析
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
@SuppressWarnings("unchecked")
public AutowiredAnnotationBeanPostProcessor() {this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);
try {this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("JSR-330'javax.inject.Inject'annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}
}
在初始化时就将反对注解退出汇合中,再应用扫描器去扫描办法、结构器、字段,如果有这些注解就进行注入。
看下怎么判断是否须要注入的
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {return annotation;}
}
return null;
}
AccessibleObject 是 Method、Field、Constructor 父类。
postProcessProperties 如何实现 bean 注入的
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取须要注入字段,办法
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {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;
}
// 上面就行获取 InjectionMetadata
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());
// 疾速从缓存中获取,如果没有加锁去解析,而后在后果放入缓存中
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);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
- InjectionMetadata 次要是汇合 bean 须要被注入类型,因为曾经解析过 bean Class 信息了,相当于解析后果装起来
看下如何去扫描办法、字段的
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// 从给定注解中判断 class 是否携带这个注解
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {return InjectionMetadata.EMPTY;}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 遍历所有 Field,找出扫描的注解,特意标注不反对 static 润饰 field
ReflectionUtils.doWithLocalFields(targetClass, field -> {MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {if (Modifier.isStatic(field.getModifiers())) {if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static fields:" + field);
}
return;
}
// 获取注解内 required 值
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 获取办法上桥接办法,因为泛型类型擦除,要对桥接办法进行安全检查,避免在调用是出现异常
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {return;}
// 获取注解
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
// 办法安全检查
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {if (Modifier.isStatic(method.getModifiers())) { // 不反对静态方法注入
if (logger.isInfoEnabled()) {logger.info("Autowired annotation is not supported on static methods:" + method);
}
return;
}
if (method.getParameterCount() == 0) {if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters:" +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 这样写是为了前面退出排在队列后面,父类属性优先于子类
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();}
while (targetClass != null && targetClass != Object.class); // 这里写得很好,向上解析父类,直到是 Object 为止
return InjectionMetadata.forElements(elements, clazz);
}
逻辑非常简单,就是依据给定注解去 class 获取指定的注解,从而获取到须要注入类型,然而几行简略的代码能够看出弱小编码能力,学习了👍。
当初须要注入对象曾经获取到,看如何注入吧
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) {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) {
try {value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {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(); // 类型转换器
Object value;
try {value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {if (!this.cached) {
Object cachedFieldValue = null;
if (value != null || this.required) {
cachedFieldValue = desc;
// 将注入关系增加到容器中,不便 bean 销毁时同步销毁
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) { // 这些都是为了缓存起来
cachedFieldValue = new ShortcutDependencyDescriptor(desc, autowiredBeanName, field.getType());
}
}
}
this.cachedFieldValue = cachedFieldValue;
this.cached = true;
}
}
return value;
}
}
次要外围是如从缓存获取到须要注入类型实例在 beanFactory.resolveDependency
中
进入 DefaultListableBeanFactory 看下
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
if (Optional.class == descriptor.getDependencyType()) {return createOptionalDependency(descriptor, requestingBeanName);
}
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {return new DependencyObjectProvider(descriptor, requestingBeanName);
}
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 懒加载 扫描 @Lazy 注解,返回一个代理对象
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
if (result == null) {result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
@Lazy 应用注解润饰 bean 或者 Class,在容器初始化化时不会立即创立,只有须要应用 bean 才会创立的。
依据类型 Optional、ObjectFactory、Provider,还有懒加载情景不同的解决,这些解决实质都是要调用 doResolveDependency 办法初始化对象,无论那种对象都要 获取原始对象而后再交给这些接口去包装加强。
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 如果这个注入是通过结构器注入,能够从结构器解析缓存中去获取注入信息点
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {return shortcut;}
Class<?> type = descriptor.getDependencyType();
// 尝试从注解中获取默认值 @Value 的 value
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
if (value != null) {if (value instanceof String) {String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ?
getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
try {return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
}
catch (UnsupportedOperationException ex) {
// A custom TypeConverter which does not support TypeDescriptor resolution...
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
}
// 多种混合类型解决,stream、collection、Map Array 这些
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {return multipleBeans;}
// 依据类型获取容器中 bean 名,返回 map key 就是 bean 名,value 初始从容器中获取对象,如果没有找到就会抛出异样了
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
if (matchingBeans.size() > 1) { // 呈现一个类型,不同实例,能够依据 @Primary, @Priority、属性名形式去配置
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {if (isRequired(descriptor) || !indicatesMultipleBeans(type)) { // 没有确定,抛出异样
return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
}
else {return null;}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();}
if (autowiredBeanNames != null) {autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) { // 这里其实就是从容器中获取实例,如果这时候没有初始化,就走下面初始化流程
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {if (isRequired(descriptor)) {raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
这个办法简略做个总结,先是解决 @Value 状况,而后通过 findAutowireCandidates 通过类型去容器中获取实例,如何实例还没有初始化,就会调用下面那个初始化过程,将初始化对象返回。依据注入类型进行相应解决,像 stream、Collection,这些混合类型都是间接增加进去。如果呈现了一个类型多个 bean 状况,这时就是就是 @Primary、@Priority 这些注解来判断或者依据属性名去和 beanName 匹配,最初将 bean 对象返回。
这里就简略看完一个 bean 初始化流程了。
总结
当初晓得了 Bean 实例化是由一个策略模式,应用反射攻打类创立的,和 BeanPostProcessor 其实并没有太多关系的。像我刚开始学 spring 时,老师就说 @Autowired 和 @Resources 向比拟,基于类型和 beanName 进行注入的,这样说不完全正确的。他是通过类型去获取 bean,如果呈现一个类型有多个 beanName,才通过 bean 和属性名进行注入。应用这么多年 Spring 了,素来没有应用过 @DependsOn、@Primary、@Priority、@Lookup 如果不看源码还不晓得有这个个性呢。看残缺个源码,对 bean 生命周期有了比拟清晰 bean 实例化 -> 属性注入 -> 执行初始化办法 -> 退出 spring 容器