Bean加载到初始化一览图
Bean的加载
package com.zhao;
import com.zhao.Interface.PressService;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class SourceCodeLearning {
public static void main(String[] args) {
//从容器中获取名字为user的bean
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
PressService pressService = (PressService) bf.getBean("pressService");
//调用bean的方法
String price = pressService.say();
System.out.println(price);
}
}
PressService pressService = (PressService) bf.getBean("pressService"); 这句代码做了bean的加载和初始化。跟进源码,得到
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 1 提取对应的beanName
final String beanName = transformedBeanName(name);
Object bean;
/**
* 检查缓存中或者实例工厂中是否有对应的实例
* 为什么首先会使用这段代码呢,
* 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖注入的时候为了避免循环依赖,
* Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
* 也就是将 ObjectFactory 加入到缓存中,一旦下一个bean创建时候需要依赖上个bean则直接使用ObjectFactory
*/
// 2 直接尝试从缓存或者 SingletonFactories 中的 ObjectFactory 中获取
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 3 返回对应的实例,有时候存在诸如BeanFactory 的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 4 只有在单例情况下才会尝试解决循环依赖,原型模式情况下,如果存在
// 4 A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A
// 4 造成循环依赖,也就是下面的情况 isPrototypeCurrentlyInCreation(beanName) 为true
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
// 5 如果 beanDefinitionMap 中也就是在所有已经加载的类中不包括 beanName 则尝试从
// 5 parentBeanFactory 中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// 递归到 BeanFactory 中寻找
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 如果不是仅仅做类型检查则是创建 bean,这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 6 将存储Xml配置文件的 GernericBeanDefinition 转换为 RootBeanDefinition,
// 6 如果指定BeanName 是子 Bean 的话同时会合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
// 7 若存在依赖则需要递归实例化依赖的bean
if (dependsOn != null) {
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);
}
}
}
// 8.1 实例化依赖的 bean 后便可以实例化 mbd 本身了
// 8.1 singleton 模式的创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 8.2 创建bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// 8 Prototype 模型的创建(new)
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
// 8 指定的 scope 上实例化 bean
String scopeName = mbd.getScope();
final 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);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 9 检查需要的类型是否符合 bean 的实际类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
}
1 提取对应的beanName
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
/** Map between containing bean names: bean name --> Set of bean names that the bean contains */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
/** Map between dependent bean names: bean name --> Set of dependent bean names */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
@Override
@Nullable
public Object getSingleton(String beanName) {
// 参数 true 设置标识允许早期依赖
return getSingleton(beanName, true);
}
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 如果为空,则锁定全局变量并进行处理
synchronized (this.singletonObjects) {
// 如果此 bean 正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 当某些方法需要提前初始化的时候则会调用 addSingletFactory 方法将对应的
// ObjectFactory 初始化策略存储在 singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用预先设定的 getObject() 方法
singletonObject = singletonFactory.getObject();
// 记录在缓存中,earlySingletonObjects 和 singletonFactories 互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
}
讲解:这个方法首先尝试从 singletonObjects 里面获取实例,如果获取不到再从 earlySingletonObjects 里面获取,如果还是获取不到,再尝试从 singletonFactories 里面获取 beanName 对应的 ObjectFactory ,然后调用这个 ObjectFactory 的 getObject 来创建bean,并放到 earlySingletonObjects 里面去,并且从 singletonObjects 里面 remove 掉这个 ObjectFactory ,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在 allowEarlyReference 为true的情况下才会使用。
简单解释两点:singletonFactories 集合中的值,类型是 ObjectFactory,这个类是用来创建bean的,可能有人不解,创建 bean 不是用反射去创建吗?为什么来了一个 ObjectFactory 创建,没错,无论什么bean最终都会通过反射来创建,但你需要在配置文件中配置你要创建的这个 bean 的各种信息。但 FactoryBean 就不同,你可以通过getObject()方法直接返回需要创建的bean。
第二点:singletonObjects 创建完 bean 后为什么要 remove 掉这个 ObjectFactory。因为这是创建单例bean,bean实例化放入 earlySingletonObjects 后,再次获取在缓存中就可以得到,就无需再保留这个 ObjectFactory 了。
这里设计用于存储 bean 的不同 map,简单解释一下:
singletonObjects :用于保存 BeanName 和创建 bean 实例之间的关系,bean name --> bean instance
singletonFactories : 用于保存 BeanName 和创建 bean 的工厂之间的关系,bean name --> ObjectFactory
earlySingletonObjects : 也是保存 BeanName 和创建 bean 实例之间的关系,与 singletonObjects 的不同之处在于,当一个单例 bean 被放到这里面后,那么当 bean 还在创建过程中,就可以通过 getBean 方法获取到了,其目的是用来检测循环引用。
registeredSingletons : 用来保存当前所有已注册的 bean
3 返回对应的实例,返回getObject()实例或者返回FactoryBean实例
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
Spring在获取bean的规则有这样一条:尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor 的 postProcessAfterInitialization 方法进行处理。在实际开发过程中大可以针对此特性设计自己的业务逻辑。
8.1 singleton 模式的创建 (在第一次加载bean的时候,缓存中没有,所以要新创建)
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 全局变量需要同步
synchronized (this.singletonObjects) {
// 首先检查对应的bean是否已经加载过,
// 因为 singleton 模式其实就是复用已创建的bean,这一步是必须的
Object singletonObject = this.singletonObjects.get(beanName);
// 如果为空才可以进行 singleton 的 bean 的初始化
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
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!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 初始化 bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 加入缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
以上代码做的事情大概是:
- 检查缓存中是否已经加载过
- 若没有加载,则记录beanName的正在加载状态,在 beforeSingletonCreation 方法中记录
- 加载单例前记录加载状态。(对循环依赖进行检测)
- 通过调用参数传入的 ObjectFactory 的个体 Object 方法实例化bean
- 加载单例后的处理方法调用(移除缓存该 bean 加载状态的记录)
- 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
- 返回处理结果
8.2 创建bean return createBean(beanName, mbd, args);
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 锁定 class,根据设置的 class 属性或者根据 className 来解析 Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
// 验证及准备覆盖的方法
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 给 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 {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
这个方法主要做了这样几件事
- 根据谁的 class 属性或者根据 className 来解析 Class
- 对 override 属性进行标记或验证
- 应用初始化前的后置处理器,解析指定的 bean 是否存在初始化前的短路操作
- 创建bean
对于第二点简单解释下,在bean实例化的时候如果检测到存在 methodOverrides 属性,会动态的为当前bean生成代理并使用对应的拦截器为 bean 做增强处理
创建 bean 前的短路,是这一步 if (bean != null) { return bean; },如果对bean增强后,bean已经创建好了,就直接返回,不会再去创建了。保证单例
第三点的代码,Bean实例化前的后置处理器,增强bean的功能
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 在实例化之前应用 Bean 后处理器
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
// 实例化之后应用 Bean 后处理器
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); 这段代码是给子类一个修改 beanDefinition 的机会,在bean实例化前会调用后处理方法进行处理。
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
实例化之后引用 bean 后处理器
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
循环依赖
对象A中有属性对象B,对象B中有属性对象A。当创建对象A时先创建A中的属性对象B,去创建对象B,又得创建对象A。
对象 A 中有属性 B
package com.zhao.service;
public class A {
private B b;
public A(B b) {
this.b = b;
}
public void sayHello() {
System.out.println("hello");
}
}
对象 B 中有属性 A
package com.zhao.service;
public class B {
private A a;
public B(A a) {
this.a = a;
}
public void sayHello() {
System.out.println("hello");
}
}
配置文件
<bean id="a" class="com.zhao.service.A"> <constructor-arg index="0" ref="b"/> </bean>
<bean id="b" class="com.zhao.service.B"> <constructor-arg index="0" ref="a"/> </bean>
启动类
package com.zhao;
import com.zhao.Interface.PressService;
import com.zhao.service.A;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class SourceCodeLearning {
public static void main(String[] args) {
//从容器中获取名字为user的bean
BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
A a = (A) bf.getBean("a");
}
}
控制台报错
这种构造方法造成的循环依赖是无法解决的。只能通过报错表示循环依赖
Spring容器将每一个正在创建的bean标识符放在一个 “当前创建bean池” 中,bean 标识符在创建过程中将一直保持在这个池中,因此如果在创建bean过程中发现自己已经在 “当前创建bean池” 里时,将抛出 BeanCurrentlyInCreationException 异常表示循环依赖;而对于创建完毕的 bean 将从 “当前创建bean池” 中清除掉。
以上是构造方法的循环依赖
Spring 对于 setter 注入方式构成的循环依赖是可以解决的,但是只能解决单例作用域的 bean 循环依赖。它是通过暴露一个单例工厂方法,从而使其它 bean 能引用到该bean。
通过
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这段代码实现。
具体步骤如下:
- Spring 容器创建单例 “A” bean,首先根据无参构造器常见 bean,并暴露一个 “ObjectFactory” 用于返回一个提前暴露一个创建中的 bean,并将 “A” 标识符放到 “当前创建 bean 池”,然后进行 setter 注入 B。
- Spring 容器创建单例 “B” bean,首先根据无参构造器常见 bean,并暴露一个 “ObjectFactory” 用于返回一个提前暴露一个创建中的 bean,并将 “B” 标识符放到 “当前创建 bean 池”,然后进行 setter 注入 A。
至此完成 setter 依赖注入,其中最大的作用就是 缓存
但是对于多例对象,Spring是无法完成依赖注入的。因为 prototype 对象,Spring 是不进行缓存的。因此无法提前暴露一个创建中的 bean.
创建Bean
前面通过代理或者将bean增强后改变了 bean,那直接返回即可。就是那个短路操作,如果经Bean实例化前的后置处理器,已经创建出代理bean了,那么就返回。如若不然,就按常规的 bean创建,这是在。Object beanInstance = doCreateBean(beanName, mbdToUse, args); 方法中完成的
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
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.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 应用 MergedBeanDefinitionPostProcessors
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
/**
* 是否需要提早曝光:单例 & 允许循环依赖 & 当前 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");
}
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
addSingletonFactory(beanName,
// 对 bean 再一次依赖引用,主要应用 SmartInstantiationAware BeanPostProcessor
// 其中我们熟知的 AOP 就是在这里将 advice 动态织入 bean 中,若没有则直接返回 bean,不做任何处理
() -> getEarlyBeanReference(beanName, mbd, bean)
);
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 对 bean 进行填充,将各个属性值注入,其中,可能存在依赖于其他 bean 的属性,则会递归初始依赖 bean
populateBean(beanName, mbd, instanceWrapper);
// 调用除耍滑方法,比如 init method
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) {
Object earlySingletonReference = getSingleton(beanName, false);
// earlySingletonReference 只有在检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
// 如果 exposedObject 没有在初始化方法中被修改,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/**
* 因为 bean创建后其所依赖的 bean 一定是已经创建的
* actualDependentBeans 不为空则表示当前 bean 创建后其依赖的 bean 却没有
* 全部创建完,也就是说存在循环依赖
*/
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 {
// 根据 scope 注册 bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
这个方法的大概思路是
- 如果是单例则需要首先清除缓存
- 实例化 bean,将BeanDefinition转换为BeanWrapper。
- MergedBeanDefinitionPostProcessors 的应用:bean合并后的处理,Autowired 注解正式通过此方法实现诸如类型的预解析
- 依赖处理
- 属性填充
- 循环依赖检查:单例可以解决,但是对于构造和多例只能抛出异常
- 注册DisposableBean:如果配置了 destroyMethod,这里需要注册以便在销毁的时候调用
- 完成创建并返回
创建bean分为了很多步,我们先从 instanceWrapper = createBeanInstance(beanName, mbd, args); 方法分析
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析class
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) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方法不为空则使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
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() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// 使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
这个方法的大概意思是
- 如果在 RootBeanDefinition 中存在factoryMethodName属性,或者说在配置文件中配置了 factoryMethod 属性,那么Spring 会尝试使用 instantiateUsingFactoryMethod(beanName, mbd, args); 方法根据 RootBeanDefinition 中的配置生成 bean 的实例
- 解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数集类型去判断最终会使用哪个构造函数进行实例化。但是,判断的过程是个比较消耗性能的步骤,所以采用缓存机制。如果已经解析过则不需要重复解析而是直接从 RootBeanDefinition 中属性 resolvedConstructorOrFactoryMethod 缓存的值去取,否则需要再次解析,并将解析的结果添加至 RootBeanDefinition 中的属性 resolvedConstructorOrFactoryMethod 中去。
实例化 bean 无非是有参构造的实例 或 无参构造的实例。这里只针对无参构造讲解,也就是 instantiateBean(beanName, mbd); 这个方法
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
如果没有参数,直接调用实例化策略进行实例化就行了,也就是 getInstantiationStrategy().instantiate(mbd, beanName, parent) 中的 instantiate 方法
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 如果有需要覆盖或者动态替换的方法则当然需要使用cglib进行动态代理,
// 因为可以在创建代理的同时将动态方法织入类中
// 但是如果没有需要动态改变的方法,为了方便直接反射就可以了
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);
}
}
程序中如果用户没有使用 replace 或者 lookup 的配置方法,那么直接使用反射的方式创建对象,如果使用了这两个属性,需要将这两个属性提供的功能切入进去,所以就必须使用动态代理的方式将包含两个逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强。
还记得我们是从哪个方法进来的吗?spring的源码就是这样,犹如洋葱,很容易忘记剥到第几层了。是 doCreateBean 这个方法,创建 bean 的,现在 bean 已经创建好了,由于咱们创建的是单例 bean,所以要在缓存中记录这个 bean 的 ObjectFactory。
是否需要提早曝光: 单例 & 允许循环依赖 & 当前 bean 正在创建中,检测循环依赖 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
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");
}
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
addSingletonFactory(beanName,
// 对 bean 再一次依赖引用,主要应用 SmartInstantiationAware BeanPostProcessor
// 其中我们熟知的 AOP 就是在这里将 advice 动态织入 bean 中,若没有则直接返回 bean,不做任何处理
() -> getEarlyBeanReference(beanName, mbd, bean)
);
}
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
Spring处理循环依赖的解决方法,在 B 中有属性A,A 此时已创建,但是还没来得及填充属性,此时 B 就调用 ObjectFactory 创建A(其实返回的还是创建的 A,地址值一样),并将填充A到自己的属性,此时 B 已初始化,将 B 属性填充给 A,使 A 初始化。解决了循环依赖
属性填充 populateBean(beanName, mbd, instanceWrapper);
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// 没有可填充的属性
return;
}
}
// 给 InstantiationAwareBeanPostProcessors 最后一次机会在属性设置前来改变 bean
// 如:可以用来支持属性注入的类型
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 返回值为是否继续填充 bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后处理器发出停止填充命令则终止后续的执行
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
// 根据名称自动注入
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
// 根据类型自动注入
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()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 对所有需要依赖检查的属性进行后处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依赖检查,对应 depends On 属性,3.0 已弃用此属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 将属性应用到 bean 中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
这大概流程是
- InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 函数的应用,此函数可以控制程序是否继续进行属性的填充
- 根据注入类型(byName / byType),提取依赖的bean,并统一存入 PropertyValues 中
- 应用 InstantiationAwareBeanPostProcessor 处理器中的 postProcessPropertyValues 方法,对属性获取完毕填充前对属性再次处理,典型应用是 RequiredAnnotationBeanPostProcessor 类中对属性的验证。
- 将所有 PropertyValues 中的属性填充至 BeanWrapper 中
其中有根据类型注入和根据Name注入
名称注入代码如下
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
// 寻找 bw 中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 递归初始化相关的 bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
// 注册依赖
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");
}
}
}
}
这段代码大概意思是
在传入的参数 pvs 中找出已经加载的 bean,并递归实例化,进而加入到 pvs 中
类型注入代码如下
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);
// 寻找 bw 中寻找依赖注入的属性
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.
if (Object.class != pd.getPropertyType()) {
// 探测指定属性的 set 方法
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);
// 解析指定 beanName 的属性所匹配的值,并把解析的属性名称存储在
// autowiredBeanNames 中,当属性存在多个封装 bean 时如:
// @Autowired private List<A> aList;将会找到所有匹配 A 类型的
// bean 并将其注入
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
// 注册依赖
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);
}
}
}
这段代码大概的意思是
寻找类型匹配的 bean,然后遍历这些属性并寻找类型匹配的 bean。 在 resolveDependency 方法中实现。
至此已经完成了所有属性的获取,但是获取的属性是以 PropertyValues 形式存在的,还没有应用到已经实例化的 bean 中,这一工作是在 applyPropertyValues 实现的
将 applyPropertyValues 中的属性注入至 bean 中
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
// 如果 mpvs 中的值已经被转换为对应的类型那么可以直接设置到 beanwapper 中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
// 如果 pvs 并不是使用 MutablePropertyValues 封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
// 获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
// 遍历属性,将属性转换为对应类的对应属性的类型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
初始化 Bean
Bean初始化,无非是调用无参构造创建 bean,创建bean前后实现一些接口就可以对 bean 进行增强,做一些自己想做的处理。博主印象最深刻的场景就是做缓存预热处理,一些热点数据频繁从数据库读取,造成数据库压力过大,于是在每次启动项目前,就将那些热点数据加载至 redis 缓存中,加载热点数据的时机就是创建 Spring 容器的时候,Spring容器对 bean 的增强是可以做到这一点
Eg:
package com.zhao.BeanLifeCycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class BeanLifecycle implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean {
/**
* 1。构造器
*/
public BeanLifecycle() {
System.out.println("1.【Bean级别】构造器执行了");
}
/**
* 2。BeanNameAware 接口方法实现
* @param name
*/
@Override
public void setBeanName(String name) {
System.out.println("2.【Bean级别】setBeanName 方法执行了");
}
/**
* 3。ApplicationContextAware 接口方法实现
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("3.【Bean级别】setApplicationContext 方法执行了");
}
/**
* 4。InitializingBean 接口方法实现
* @throws Exception
*/
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("4.【Bean级别】afterPropertiesSet 方法执行了");
}
/**
* 5。init-method 指定的方法执行了
*/
public void lifecycleInit(){
System.out.println("5.【Bean级别】init-method 指定的方法执行了");
}
/**
* 6。sayHello 方法执行了
*/
public void sayHello(){
System.out.println("6.【Bean级别】sayHello 方法执行了");
}
/**
* 7。DisposableBean 接口方法实现
* @throws Exception
*/
@Override
public void destroy() throws Exception {
System.out.println("7.【Bean级别】destroy 方法执行了");
}
/**
* 8。destroy-method 指定的方法执行了
*/
public void lifecycleDestroy(){
System.out.println("8.【Bean级别】destroy-method 指定的方法执行了");
}
}
启动类
package com.zhao;
import com.zhao.BeanLifeCycle.BeanLifecycle;
import com.zhao.Interface.PressService;
import com.zhao.service.A;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class SourceCodeLearning {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanLifecycle bean = (BeanLifecycle) app.getBean("beanLifecycle", BeanLifecycle.class);
bean.sayHello();
app.close();
}
}
打印结果
后处理器,容器级接口方法
package com.zhao.BeanLifeCycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import java.beans.PropertyDescriptor;
/**
*
*/
public class ContainerLifecycle extends InstantiationAwareBeanPostProcessorAdapter {
/**
* 构造器
*/
public ContainerLifecycle() {
System.out.println("⓵.【容器级别】ContainerLifecycle 构造器执行了");
}
/**
* 接口方法和实例化 Bean 之前调用
* @param beanClass
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("⓶.【容器级别】postProcessBeforeInstantiation 方法执行了,class= "+beanClass);
return null;
}
/**
* 设置某个属性时调用
* @param pvs
* @param pds
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
System.out.println("⓷.【容器级别】postProcessPropertyValues 方法执行了,beanName= "+bean.getClass());
return pvs;
}
/**
* 接口方法和实例化 Bean 之后调用
* @param bean
* @param beanName
* @return
* @throws BeansException
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("⓸.【容器级别】postProcessAfterInitialization 方法执行了,beanName= "+bean.getClass());
return null;
}
}
打印结果
可以发现,每创建一个 bean,就会调用一次容器接口方法
而且容器级别的销毁方法要先于 bean级别的销毁方法
工厂级别的接口方法
package com.zhao.BeanLifeCycle;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
public class FactoryLifecycle implements BeanFactoryPostProcessor {
/**
* 构造器
*/
public FactoryLifecycle() {
System.out.println("一 【工厂级别】FactoryLifecycle 构造器执行了");
}
/**
* Bean 实例化之前
* @param beanFactory
* @throws BeansException
*/
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("二 【工厂级别】postProcessBeanFactory 方法执行了");
}
}
启动引导类
package com.zhao;
import com.zhao.BeanLifeCycle.BeanLifecycle;
import com.zhao.Interface.PressService;
import com.zhao.service.A;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
* Bean 级别 + 容器级 + 工厂级
*/
public class SourceCodeLearning {
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
BeanLifecycle bean = (BeanLifecycle) app.getBean("beanLifecycle", BeanLifecycle.class);
bean.sayHello();
app.close();
}
}
打印结果
实现了 BeanFactoryPostProcessor,工厂级别的 postProcessBeanFactory,最先执行,而且只会执行一次
当我们执行完实例化 bean 后,还记得是从哪个方法进来的吗?是在doCreateBean 方法中属性填充完成后,调用 exposedObject = initializeBean(beanName, exposedObject, mbd); 进行初始化的,下面的方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 对特殊的 bean 处理:Aware,BeanClassLoaderAware,BeanFactorAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 应用后处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 激活用户自定义的 init 方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 后处理器应用
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
Bean级别的方法:
实现各种 Aware 接口,如:BeanNameAware,BeanFactoryAware,ResourceLoaderAware,ApplicationContextAware,InitializingBean 等
// Bean 级别的方法
// 实现了 aware 接口的方法
private void invokeAwareMethods(final String beanName, final Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
// 配置了 Init-Method 属性或者实现了 InitlizingBean 接口
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 首先会检查是否是 InitlizingBean,如果是的话需要调用 afterPropertiesSet 方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 属性初始化后的处理
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 调用自定义的初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
容器级别的方法:BeanPostProcessor
在调用客户自定义初始化方法前以及调用自定义的初始化方法后分别会调用 postProcessBeforeInstantiation 和 postProcessAfterInitialization 方法,使用户可以根据自己的业务需求进行相应的处理
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
销毁的方法
在 AbstractBeanFactory 类中 registerDisposableBeanIfNecessary 方法
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// 单例模式下注册需要销毁的 bean,此方法中会处理实现 DisposableBean 的 Bean
// 并且对所有的 bean 使用 DestructionAwareBeanPostProcessor 处理,
// DisposableBean DestructionAwareBeanPostProcessor
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// 自定义 scope 的处理
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}