本文引自我的个人博客: sunmingshuai.coding.me
在refresh()
方法中 最重要的方法有两个 分别是obtainFreshBeanFactory()
与 finishBeanFactoryInitialization(beanFactory)
第一个方法我们已经讲解过了 现在我们看下第二个方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
//重要 实例化所有的非懒惰加载的bean
beanFactory.preInstantiateSingletons();
}
到beanFactory.freezeConfiguration()
这里的时候 就不再允许改变配置文件了 因为可能会影响到后面的加载过程
如果bean
是单例模式 并且没有设置懒惰加载的话 就预先实例化这个bean
调用DefaultListableBeanFactory#preInstantiateSingletons()
方法 DefaultListableBeanFactory
是个很重要的类 承载了很多功能 读者可以借助编辑器查看下这个类的继承关系
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isInfoEnabled()) {
this.logger.info("Pre-instantiating singletons in " + this);
}
List<String> beanNames;
synchronized (this.beanDefinitionMap) {
beanNames = new ArrayList<String>(this.beanDefinitionNames);
}
// 循环检查所有的bean 并按情况加载
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//如果是工厂bean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
}
对于beanFactory
中的每一个bean
先根据beanName
获取BeanDefinition
因为我们所需要的属性等都在这个类里面了 调用getMergedLocalBeanDefinition(beanName)
方法获得 这里需要考虑的一个问题就是如果设置了parent
属性的话(在由xml文件载入BeanDefinition
的时候 parent
属性被当作普通属性来对待 并没有做什么特殊处理)
<bean id="xxx" class="com.xxx.xxx" parent="TestXXX"/>
那么就需要跟parent
所指向的BeanDefinition
的配置属性合并后再返回了. 当然这里肯定是个递归调用 因为parent
本身可能也定义了自己的parent
属性 合并的原则是先拷贝父类的所有属性元素,然后与子类的合并,如果有属性名一样的话,则覆盖.
在满足下面三个条件的时候 才会尝试加载
- 不是抽象类
- 单例模式
- 没有设置懒惰加载
如果是FactoryBean
的话 那么就需要考虑是返回FactoryBean
本身 还是返回FactoryBean#getObect()
方法返回的对象 spring约定 如果要返回FactoryBean
本身 那么需要在beanName
前加上约定的&
符号 否则就是返回T getObject()
我们看一下FactoryBean
的接口定义 很显然 这是利用了工厂方法
public interface FactoryBean {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}
下面的源码内容 对于读者来说 比较难理解 对于作者本人来说比较难讲解 一个是涉及到的内容比较多 比如 FactoryBean
循环依赖
代理
属性填充
BPP
寻找构造函数
等 另外一个是功能间咬合
比较多 下文介绍的时候 我们就不考虑那么多 先把最简单的情况介绍到 如下面的代码实例:第一次加载 有默认构造函数 TestA
中有一个java基本类型 一个引用类型 init-method
属性, 在了解加载TestA
的加载的基础上 再去了解那些扩展功能
当然对于TestA的加载其实过程很简单 简单叙述来说 就是根据TestA.class实例化TestA 这里用的是默认的构造函数 然后是属性的填充 调用init()方法等
public class TestA{
private String a;
private TestB b;
@Autowired
private TestC c;
// getXXX setXXX
public void init(){
System.out.println("Hello World");
}
}
public class TestB{
private int c;
}
____________________________
......
<!-- -->
<component:scan basepackage="com.xxx.xxx"/>
<bean id="testA" class="com.xxx.xxx.TestA">
<property name="b" ref=" />
</bean>
<bean id="testB" class="com.xxx.xxx.TestB"/>
<bean id="testC" class="com.xxx.xxx.TestC"/>
......
AbstractBeanFactory#doGetBean(...)
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 如果是别名 就返回对应的真实的beanName
// 如果以&开头 先去除
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
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 + "'");
}
}
//todo 待看
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//依赖分为三种依赖: 原型循环依赖 构造器循环依赖 单例循环依赖
//只有单例依赖才能解决 其他情况只能抛出异常
//原型循环依赖 无法解决 抛异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果这个容器中没有bean的定义的话 去父容器中加载
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//还原beanName
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//返回配置文件定义的bean的定义信息 GenericBeanDefinition->RootBeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 先加载配置中`depend-on`属性中配置的`bean`
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
// 单例模式
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
//核心加载部分
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
//获取到的bean可能是FactoryBean类型的bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型模式
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);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
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;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
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;
}
在getSingleton(beanName)
的调用中 其实处理了好几种情况
- 是否已经加载完成过 bean的加载是个耗时的过程 加载完成后就放到map中保存 有就直接返回
- 没有加载完成 并且知道正在创建中 那么说明是遇到了循环依赖问题
对于循环依赖问题 以后有时间会单独开一个博客讲解 这里简单介绍下 首先对于都是单例模式来说 会遇到两种循环依赖问题构造器循环依赖
set循环依赖
举例如下
//构造器循环依赖
public class TestA(){
...
public TestA(TestB b){
}
...
}
public class TestB(){
...
public TestB(TestA a){
}
...
}
//set循环依赖
public class TestA(){
...
@Autowired
private TestB b;
...
}
public class TestB(){
...
@Autowired
private TestA a;
...
}
构造器循环依赖 是不能够被解决的 原因如下:在实例化TestA
的时候需要去实例化TestB
然后去实例化TestB
然后这个时候又发现需要TestA
所以两个都不能完成实例化
而对于set依赖来说 虽然也存在循环依赖 但问题却能够得到解决 解释如下:TestA
实例化完成后 在给TestA
填充属性的过程中发现需要TestB
存下TestA
的引用 然后去获取TestB
实例化TestB
后 给TestB
填充属性的过程中发现需要TestA
然后再去获取TestA
之前埋入了TestA
的引用 (虽然还没加载完整) 这个时候返回TestA
的引用 这个时候TestB
加载完成 回去继续加载TestA
这个时候循环依赖也就没有了
Spring
通过记录不同状态下的引用 即提前暴露地址的方式解决循环依赖
在第一次讲解的时候 我们暂且不考虑那么多 我们就当成我们现在的情况是第一次加载这个bean
并且不存在循环依赖的情况 当然我们还是可以看下他们额外做了写什么 大概有个印象
我们回到getSingleton(...)
方法 里面有两个map 一个是earlySingletonObjects
另外一个是singletonFactories
这两个map中的东西似乎是互斥的.
如果这个时候获得到了的话 就返回 然后再通过getObjectForBeanInstance
处理 这个方法主要判断返回的是不是我们最终想要的 如果是FactoryBean
类型的话 还需要进一步处理
我们看下单例模式下的bean
的加载
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
//核心加载部分
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while the singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
//时间节点 放入singletonsCurrentlyInCreation 代表这个bean正在加载中
beforeSingletonCreation(beanName);
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
singletonObject = singletonFactory.getObject();
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
//时间节点 从singletonsCurrentlyInCreation中清除 代表创建完成
afterSingletonCreation(beanName);
}
//加入到singletonObjects中 从singletonFactories earlySingletonObjects中去除
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
我们看下singletonFactory
回调方法createBean
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// 获取class属性
resolveBeanClass(mbd, beanName);
// Prepare method overrides.
try {
//look-method replace-method配置项检查处理 如果不清楚的可以先搜索相关使用demo
mbd.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// todo AOP功能实现 `AnnotationAwareAspectJAutoProxyCreator`
// [看另外一篇博客](http://www.sunmingshuai.cn/2017/05/22/aop%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90%E4%B8%80/)
Object bean = resolveBeforeInstantiation(beanName, mbd);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
Object beanInstance = doCreateBean(beanName, mbd, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
如果我们有对类进行代理的话 那么返回的就是代理类 而不是裸类 这个处理就是在resolveBeforeInstantiation
方法中处理的 这里不深入研究 想了解的可以看博主的另外的博客介绍 aop源码解析一:注册BPP aop源码解析二:寻找Advisor
方法又转到了doCreateBean(beanName,mnb,args)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//判断采用哪种实例化方法 factoryMethod | 构造器(如果有多个构造器还需要根据args判断采用哪个构造器构造)
//如果有配置replace-method lookup-method 会创建代理
//注册属性编辑器
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
//todo ## BPP触发的另一个地方 如处理@AutoWired注解的AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition()
// [component-scan做了些什么:源码解读](http://www.sunmingshuai.cn/2017/04/28/component-scan%E5%81%9A%E4%BA%86%E4%BA%9B%E4%BB%80%E4%B9%88/)
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// 提前加入缓存 以辩能够解决循环引用问题
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");
}
// 解决循环依赖问题的关键 提前把ObjectFactory加入进来 如果有碰到循环依赖的话 通过ObjectFactory获取bean
// 因为他们代表的地址是一样的
addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// 初始化bean的实例
Object exposedObject = bean;
try {
// bean属性的填充(xml文件定义的属性 被@Autowired @Value等注解修饰 以及一些其他属性 IOC的直接体现
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
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) {
// 再一次调用`getSingleton()`方法 只是这一次`allowEarlyReference`为false
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
这里会判断采用哪种方式实例化bean
如果采用有参构造函数的形式的话 匹配逻辑稍微有点复杂 实例化后会注册一些属性编辑器 就是把string
类型的参数值能够转化为我们想要的类型值
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
方法是spring
的一个扩展方法 例如我们常用的@Autowired
就在这个方法里预先处理了一下 找出该bean
的标注有@Autowited
所有的field
与method
并放入合适的数据结构保存 我们这里就不展开讲解了
addSingletonFactory
这个方法逻辑不难 却意义重大 到这个阶段的时候 就把这个bean
提前暴露出来了 就能够解决我们前面所说的第二种依赖了
populateBean(beanName, mbd, instanceWrapper)
方法的作用就是bean
属性的填充 我们说的IOC
DI
的体现就是在这里了 由spring
框架给我们注入我们想要的
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if (bw == null) {
if (!pvs.isEmpty()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// 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.
boolean continueWithPropertyPopulation = true;
//实例化后的后置处理器 spring框架的扩展点
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;
}
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// xml文件中定义的非java基本类型依赖 在这里就注入了 byName
if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// xml文件中定义的非java基本类型依赖 在这里就注入了 byType
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);
// @Autowired注解实现注入就是在这里
if (hasInstAwareBpps || needsDepCheck) {
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) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
//
applyPropertyValues(beanName, mbd, bw, pvs);
}
这里涉及到的几个BPP我们后面会挑一个出来讲解 如@Autowired注解的实现过程 这里就不深入讨论了 属性填充完后就到了init的环节 initializeBean(beanName, exposedObject, mbd)
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 这个时间点是属性填充完了 但是还没有调用initMethod方法的阶段
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
//如果有继承xxxAware的话 调用setXXX相应的方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//initMethod方法调用前
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用initMethod 或者 afterPropertiesSet方法
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;
}
这个方法相对来说比较简单 有几点说一下 读者可能用过xxxAware
然后继承setXXX
方法就可以了 那么是怎么实现的呢 答案很简单 spring
会判断是哪个aware
然后调用响应的set方法 即invokeAwareMethods
的方法实现
我们前面说过初始化方法执行前后是个特殊的时间节点 spring自然不会忘记在其执行前后添加一些扩展点 就是调用BPP
的扩展方法
对于初始化来说 spring提供了一个类似功能的接口供我们继承InitializingBean
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
跟init-method
要实现的功能差不多
初始化完成后 bean
的加载基本上就算完成了