Spring源码学习(5)—— bean的加载 part 2

时间:2023-03-08 23:48:20
Spring源码学习(5)—— bean的加载 part 2

之前归纳了从spring容器的缓存中直接获取bean的情况,接下来就需要从头开始bean的加载过程了。这里着重看单例的bean的加载

if(ex1.isSingleton()) {
sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, ex1, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
}

单例的加载调用了重载的getSingleton方法,在这个方法的参数中,传入了一个实现ObjectFactory接口的匿名内部类对象,在接口方法中调用了外部类AbstractBeanFactory的createBean方法来创建bean,同时在捕获异常时,调用外部类的destroySingleton方法执行一系列销毁操作。

我们进入到getSingleton方法

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "\'beanName\' must not be null");
Map var3 = this.singletonObjects;
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 singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
} if(this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean \'" + beanName + "\'");
} this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if(recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
} try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if(singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if(recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator(); while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
} throw ex;
} finally {
if(recordSuppressedExceptions) {
this.suppressedExceptions = null;
} this.afterSingletonCreation(beanName);
} if(newSingleton) {
this.addSingleton(beanName, singletonObject);
}
} return singletonObject != NULL_OBJECT?singletonObject:null;
}
}

在这段代码中首先会检查当前bean是否在销毁过程中,一旦销毁过程还未结束,说明当前容器中部分缓存并不准确,因此会抛出异常。

在执行ObjectFactory的getObject方法前,执行了一段创建前的操作代码

protected void beforeSingletonCreation(String beanName) {
if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}

在这里把beanName放在了singletonsCurrentlyInCreation缓存中,也就是说在这一刻,spring声明正在创建这个bean了。

同样的在调用ObjectFactory的getObject方法后,在finally块里afterSingletonCreation中,spring会在singletonsCurrentlyInCreation将其移除。

protected void afterSingletonCreation(String beanName) {
if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton \'" + beanName + "\' isn\'t currently in creation");
}
}

若创建bean成功了,就会调用addSingleton方法,更新一系列容器的缓存。

    protected void addSingleton(String beanName, Object singletonObject) {
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject != null?singletonObject:NULL_OBJECT);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

这样之后再创建这个单例bean的时候只需要从singletonObjects中取就ok了。

接下来我们就来看看真正创建bean的代码段singletonObject = singletonFactory.getObject()

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Creating instance of bean \'" + beanName + "\'");
} RootBeanDefinition mbdToUse = mbd;
Class resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if(resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
} try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var7) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var7);
} Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if(beanInstance != null) {
return beanInstance;
}
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
} beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if(this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean \'" + beanName + "\'");
} return beanInstance;
}

在这段中,首先根据设置的class属性或者根据className来解析Class。

然后会对beanDefinition中的methodOverrides属性做一个预处理。在methodOverrides中存放的是先前随笔中提到的lookup-method和replace-method标签的解析。目的是对生成的bean的对应方法中实现一层代理。

    public void prepareMethodOverrides() throws BeanDefinitionValidationException {
MethodOverrides methodOverrides = this.getMethodOverrides();
if(!methodOverrides.isEmpty()) {
Set overrides = methodOverrides.getOverrides();
synchronized(overrides) {
Iterator var4 = overrides.iterator(); while(var4.hasNext()) {
MethodOverride mo = (MethodOverride)var4.next();
this.prepareMethodOverride(mo);
}
}
} }
    protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
int count = ClassUtils.getMethodCountForName(this.getBeanClass(), mo.getMethodName());
if(count == 0) {
throw new BeanDefinitionValidationException("Invalid method override: no method with name \'" + mo.getMethodName() + "\' on class [" + this.getBeanClassName() + "]");
} else {
if(count == 1) {
mo.setOverloaded(false);
} }
}

根据上面两段代码可以看出,这里的预处理就是如果在当前类中没有找到对应要代理的方法时,就抛出异常,如果根据方法名只找到一个对应的方法,说明要代理的方法就是这个方法。那么就设置methodOverrides的overload属性为false。如果有多个重载的方法,那就需要根据参数来确定要代理的方法了,这一步将在之后的代码中实现。

在真正调用doCreate的方法创建bean之前,会通过resolveBeforeInstantiation做一些实例化前的前置处理。

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Class targetType = this.determineTargetType(beanName, mbd, new Class[0]);
if(targetType != null) {
bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if(bean != null) {
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
} mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
} return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
Iterator var3 = this.getBeanPostProcessors().iterator(); while(var3.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var3.next();
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if(result != null) {
return result;
}
}
} return null;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator var4 = this.getBeanPostProcessors().iterator(); do {
if(!var4.hasNext()) {
return result;
} BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
result = beanProcessor.postProcessAfterInitialization(result, beanName);
} while(result != null); return result;
}

上面的代码逻辑不复杂,就是:

1、遍历一遍AbstractBeanFactory里的BeanPostProcessors

2、然后在实例化前调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法。

3、一旦postProcessBeforeInstantiation方法返回的对象不为null,再调用BeanPostProcessor的 postProcessAfterInitialization对象

在spring中随处可见这种在做一件事情时,分别在做之前调用前处理器,而在做之后调用后处理器。这样其实就是利用模板方法,抽象出最简单最基本的不变的过程:做之前,做的过程中,做之后。这样做法的好处就是可以很方便扩展。在我们实际设计的时候可以借鉴这种写法。

如果我们想对某个特殊的bean实例化前和实例化后做一些特殊处理,就可以通过AbstractBeanFactory的addBeanPostProcessor来添加后处理器,从而实现自定义的业务逻辑。

接下来就到了常规bean的创建了,这一过程是在doCreateBean方法中实现的

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
} if(instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
} final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
Class beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
mbd.resolvedTargetType = beanType;
Object earlySingletonExposure = mbd.postProcessingLock;
synchronized(mbd.postProcessingLock) {
if(!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
} mbd.postProcessed = true;
}
} boolean var20 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if(var20) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references");
} this.addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
} Object exposedObject = bean; try {
this.populateBean(beanName, mbd, instanceWrapper);
if(exposedObject != null) {
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
} catch (Throwable var18) {
if(var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
} throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
} if(var20) {
Object ex = this.getSingleton(beanName, false);
if(ex != null) {
if(exposedObject == bean) {
exposedObject = ex;
} else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
LinkedHashSet actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length; for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if(!this.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.");
}
}
}
} try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}

这段代码比较长,阅读起来有些难度,但把这个方法一小段一小段拆分开来,还是可以看懂其中的逻辑的。

首先需要创建这个bean的实例,实例的创建在createBeanInstance方法中。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
Class beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
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());
} else if(mbd.getFactoryMethodName() != null) {
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
boolean resolved = false;
boolean autowireNecessary = false;
if(args == null) {
Object ctors = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
if(mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
} if(resolved) {
return autowireNecessary?this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null):this.instantiateBean(beanName, mbd);
} else {
Constructor[] ctors1 = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
return ctors1 == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)?this.instantiateBean(beanName, mbd):this.autowireConstructor(beanName, mbd, ctors1, args);
}
}
}

在上面的代码中我们可以看到:

1、如果这个bean有对应的工厂方法的话,调用instantiateUsingFactoryMethod来做实例化操作

2、如果不是工厂方法,则解析构造函数,并根据构造函数来实例化bean。一个bean的构造函数可能会有多个,因此,spring会根据参数类型来确定使用哪一个构造函数进行实例化,这里spring用了一个缓存机制,如果缓存resolvedConstructorOrFactoryMethod中有值,则用这个方法实例化,否则,需要再次解析,并将解析结果添加至缓存中。

我们先来看使用工厂实例化bean的情况。代码比较长,这边就不完整贴过来了,简单截取一些片段来看

 if(factoryBeanName != null) {
if(factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "factory-bean reference points back to the same bean definition");
} factoryBean = this.beanFactory.getBean(factoryBeanName);
if(factoryBean == null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "factory-bean \'" + factoryBeanName + "\' (or a BeanPostProcessor involved) returned null");
} if(mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new IllegalStateException("About-to-be-created singleton instance implicitly appeared through the creation of the factory bean that its bean definition points to");
} factoryClass = factoryBean.getClass();
isStatic = false;
} else {
if(!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "bean definition declares neither a bean class nor a factory-bean reference");
} factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}

这里判断了一下factoryBeanName是否为空,

1、如果不为空,这就说明工厂方法不是静态static的,因此需要先去实例化factoryBean

2、如果为空,则说明工厂方法是静态的。工厂就是当前bean中的class。

接下来spring会根据参数类型找到对应的工厂方法,然后通过反射来实例化bean

 Method ex = (Method)currentlyInvokedFactoryMethod.get();

            Object msg1;
try {
currentlyInvokedFactoryMethod.set(factoryMethod);
msg1 = factoryMethod.invoke(factoryBean, args);
} finally {
if(ex != null) {
currentlyInvokedFactoryMethod.set(ex);
} else {
currentlyInvokedFactoryMethod.remove();
} } return msg1;

如果没有工厂方法来实例化bean,那么对于实例的创建spring中分成了两种情况,一种是通用的实例化,一种是带参数的实例化。

我们首先来看看参数的实例化过程autowireConstructor。这个方法代码较长,就不完整摘出,直接挑一些片段来解析

首先spring会尝试拿到构造函数的参数

if(explicitArgs != null) {
argsToUse = explicitArgs;
} else {
Object[] ex = null;
Object ctorToUse = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
constructorToUse = (Constructor)mbd.resolvedConstructorOrFactoryMethod;
if(constructorToUse != null && mbd.constructorArgumentsResolved) {
argsToUse = mbd.resolvedConstructorArguments;
if(argsToUse == null) {
ex = mbd.preparedConstructorArguments;
}
}
} if(ex != null) {
argsToUse = this.resolvePreparedArguments(beanName, mbd, bw, constructorToUse, ex);
}
}

从上面的代码我们可以看到,如果在调用getBean()方法是直接添加了参数,那么就直接使用这些参数,即explicitArgs。

如果没有传参,则需要解析配置文件,在解析前,spring会先从beanDefinition的缓存中尝试获取构造函数的参数。

如果没有,则从配置的构造函数中取。

确定了构造函数的参数类型和个数,就能找到对应的构造方法了

在匹配之前,spring先对构造函数按照public构造函数优先参数数量降序,非public构造函数参数数量降序,然后根据参数来匹配找到对应的构造函数。

找到构造函数之后,就会根据实例化策略以及构造函数和构造函数参数,来实例化bean

public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, final Constructor<?> ctor, Object... args) {
if(bd.getMethodOverrides().isEmpty()) {
if(System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
ReflectionUtils.makeAccessible(ctor);
return null;
}
});
} return BeanUtils.instantiateClass(ctor, args);
} else {
return this.instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}

通过上面的实例化策略可以看到,如果bean的配置中没有methodOverrides属性,也就是lookup-method或者replace-method,那么就可以简单地通过已知的构造函数和入参来实例化对象。如果一旦有需要做代理的方法的话,spring会通过cglib动态代理的方式对这个bean做代理。这部分内容会在AOP的章节再做详细分析。

完成了bean的实例化,接下来

boolean var20 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if(var20) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references");
} this.addSingletonFactory(beanName, new ObjectFactory() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}

spring会记录创建bean的ObjectFactory,这里的singletonFactory是为了处理循环依赖的时候,可以提前使用这个bean的引用。

举个例子:假设有A和B两个bean,在A中有B的属性,B中有A的属性。这就形成了一个属性的循环依赖。spring对于属性的循环依赖是可以解决的。解决的方式就是

1、在实例化A完成后,先暴露出一个A的引用

2、接下来在注入A的属性时,发现了B,spring就会去实例化B

3、实例化B之后,B会暴露一个B的引用

4、接下来就会注入B的属性,这时候发现了A,因为A已经提前暴露了它的引用,因此B可以完成属性的注入

5、完成了B的创建后,B会将自己暴露的引用删除

6、接下来A将创建好的B注入到自己的属性中,完成A的创建,最后将A自己的暴露引用删去。

完成了属性注入populateBean,接下来就到了bean的初始化

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if(System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
return null;
}
}, this.getAccessControlContext());
} else {
this.invokeAwareMethods(beanName, bean);
} Object wrappedBean = bean;
if(mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
} try {
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null?mbd.getResourceDescription():null, beanName, "Invocation of init method failed", var6);
} if(mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
} return wrappedBean;
}

首先,spring会激活Aware方法

private void invokeAwareMethods(String beanName, Object bean) {
if(bean instanceof Aware) {
if(bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
} if(bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
} if(bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
} }

如果这个bean继承了Aware接口,那么在这里会调用Aware相应的方法。

接下来,spring会激活当前容器中注册的所有处理器方法。

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator var4 = this.getBeanPostProcessors().iterator(); do {
if(!var4.hasNext()) {
return result;
} BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
} while(result != null); return result;
}

通过BeanPostProcessor,使得我们可以自定义一些创建bean的业务逻辑

之后spring会激活自定义的init方法

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
boolean isInitializingBean = bean instanceof InitializingBean;
if(isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Invoking afterPropertiesSet() on bean with name \'" + beanName + "\'");
} if(System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
((InitializingBean)bean).afterPropertiesSet();
return null;
}
}, this.getAccessControlContext());
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} else {
((InitializingBean)bean).afterPropertiesSet();
}
} if(mbd != null) {
String initMethodName = mbd.getInitMethodName();
if(initMethodName != null && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
this.invokeCustomInitMethod(beanName, bean, mbd);
}
} }

这里的init方法除了我们在配置中设定的init-method,还可以是实现了InitializingBean接口的bean,spring会调用接口的afterPropertiesSet方法。

到这里bean的实例化和初始化就都完成了。