getBean的大致总流程如下:
下面只记录bean实例化到初始化的过程以及期间spring提供可以扩展的点。从下面getBean开始
public static void main(String []args){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
System.out.println("======================");
System.out.println(applicationContext.getBean("people"));
System.out.println("======================");
}
@ImportResource("spring-ioctest.xml")
@Configuration
@ComponentScan(value = "com.my.ioc.pojo.beanpostprocessor")
//@Import({ Myregister.class,MyImport.class})
public class BeanConfig {
@Bean
@Scope("prototype")
// @Conditional(MyConditional.class)
public People people(){
return new People();
}
@Bean
public Bird bird(){
Bird bird = new Bird();
bird.setName("bad bird");
return bird;
}
}
People里自动注入了Brid为了验证后面的问题:
一直往后跟,会走到AbstractBeanFactory.doGetBean, 直接从 // Create bean instance开始看,前面都是从单例对象池中获取(如果获取到了就返回),从父工厂获取,从factorybean中获取,检查是否存在循环依赖,这种循环依赖是通过DependsOn相互依赖的,无法解决则抛出异常,判断是否为抽象的。抽象的类不会创建。
从创建单例的这个分支进去查看:
首先调用getSingleton方法,第二个参数为lambda表达式,里面会被调用。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name 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 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);//单例创建之前进行的操作,检查这个bean是否正在被创建,如果不是就把它加到正在被创建的inCreationCheckExclusions中
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject(); //执行第二个参数的lambda表达式
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;
}
}
lambda表达式中会调用createBean方法:AbstractAutowireCapableBeanFactory.createBean(beanName, mbd, args);
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);//创建bean首先加载到对应的class,因为mbd.getBeanClassName大部分时候都是类的全限定名
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一次机会,可以返回一个对象,如果能返回,就不走spring自己 doCreateBean来创建了,这个地方我们进行扩展。
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); //spring内部创建bean的实例
if (logger.isTraceEnabled()) {
logger.trace("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);
}
}
resolveBeforeInstantiation(beanName, mbdToUse);我们进去看:
@Nullable
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()) { //判断是用户自己创建的bean而不是spring内部的bean,而且要看有没有实现InstantiationAwareBeanPostProcessor接口
Class<?> targetType = determineTargetType(beanName, mbd); //获取要创建的bean的class,有可能beanName对应的是个factoryBean,需要获取factoryBean中的类型
if (targetType != null) {
// 调用InstantiationAwareBeanPostProcessor实现类中的postProcessBeforeInstantiation方法这是实例化之前的方法
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//前置方法调用完,调用所有BeanPostProcessors的 postProcessAfterInitialization,bean初始之后的方法,因为上一步bean返回不为空,说明我们自定义的类已经实例化并初始化好了
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) { //会判断只走 InstantiationAwareBeanPostProcessor的实现类
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
applyBeanPostProcessorsAfterInitialization(bean, beanName);
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) { //没有加判断,都会走到
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
我们实现 InstantiationAwareBeanPostProcessor ,来看下效果。
接口说明:
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
/**
* Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>.
* The returned bean object may be a proxy to use instead of the target bean,
* effectively suppressing default instantiation of the target bean.
* <p>If a non-null object is returned by this method, the bean creation process
* will be short-circuited. The only further processing applied is the
* {@link #postProcessAfterInitialization} callback from the configured
* {@link BeanPostProcessor BeanPostProcessors}.
* <p>This callback will be applied to bean definitions with their bean class,
* as well as to factory-method definitions in which case the returned bean type
* will be passed in here.
* <p>Post-processors may implement the extended
* {@link SmartInstantiationAwareBeanPostProcessor} interface in order
* to predict the type of the bean object that they are going to return here.
* <p>The default implementation returns {@code null}.
* @param beanClass the class of the bean to be instantiated
* @param beanName the name of the bean
* @return the bean object to expose instead of a default instance of the target bean,
* or {@code null} to proceed with default instantiation
* @throws org.springframework.beans.BeansException in case of errors
* @see #postProcessAfterInstantiation
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getBeanClass()
* @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName()
*/
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* Perform operations after the bean has been instantiated, via a constructor or factory method,
* but before Spring property population (from explicit properties or autowiring) occurs.
* <p>This is the ideal callback for performing custom field injection on the given bean
* instance, right before Spring's autowiring kicks in.
* <p>The default implementation returns {@code true}.
* @param bean the bean instance created, with properties not having been set yet
* @param beanName the name of the bean
* @return {@code true} if properties should be set on the bean; {@code false}
* if property population should be skipped. Normal implementations should return {@code true}.
* Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor
* instances being invoked on this bean instance.
* @throws org.springframework.beans.BeansException in case of errors
* @see #postProcessBeforeInstantiation
*/
// 这个时候得到的Object bean已经是实例化的了,可以根据beanName进行强转,然后进行想要的操作,这个方法在填充属性之前调用的,自己实现方法要默认返回true不然,不会走spring自己的
// 属性注入的逻辑了
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
/**调用到这里,属性值还没有赋值到bean对象里面,只是获取到了属性值到pvs中了。所以这里可以对bean的属性值进行操作。
* spring中解析@Autowired @Value就是在这里。pvs中存的是spring将要赋值给bean的属性值。这个方法的返回值默认为空,表示要自己实现赋值
* 逻辑,这时候就要实现postProcessPropertyValues方法,spring在填充属性逻辑里如果postProcessProperties返回为null,就会调用
* postProcessPropertyValues方法,但是spring不建议使用这个方法了,已经设置为过期了.
* 所以spring建议如果要实现这个类,这个方法如果不做特殊处理就这直接返回pvs。
* Post-process the given property values before the factory applies them
* to the given bean, without any need for property descriptors.
* <p>Implementations should return {@code null} (the default) if they provide a custom
* {@link #postProcessPropertyValues} implementation, and {@code pvs} otherwise.
* In a future version of this interface (with {@link #postProcessPropertyValues} removed),
* the default implementation will return the given {@code pvs} as-is directly.
* @param pvs the property values that the factory is about to apply (never {@code null})
* @param bean the bean instance created, but whose properties have not yet been set
* @param beanName the name of the bean
* @return the actual property values to apply to the given bean (can be the passed-in
* PropertyValues instance), or {@code null} which proceeds with the existing properties
* but specifically continues with a call to {@link #postProcessPropertyValues}
* (requiring initialized {@code PropertyDescriptor}s for the current bean class)
* @throws org.springframework.beans.BeansException in case of errors
* @since 5.1
* @see #postProcessPropertyValues
*/
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
/**
* Post-process the given property values before the factory applies them
* to the given bean. Allows for checking whether all dependencies have been
* satisfied, for example based on a "Required" annotation on bean property setters.
* <p>Also allows for replacing the property values to apply, typically through
* creating a new MutablePropertyValues instance based on the original PropertyValues,
* adding or removing specific values.
* <p>The default implementation returns the given {@code pvs} as-is.
* @param pvs the property values that the factory is about to apply (never {@code null})
* @param pds the relevant property descriptors for the target bean (with ignored
* dependency types - which the factory handles specifically - already filtered out)
* @param bean the bean instance created, but whose properties have not yet been set
* @param beanName the name of the bean
* @return the actual property values to apply to the given bean (can be the passed-in
* PropertyValues instance), or {@code null} to skip property population
* @throws org.springframework.beans.BeansException in case of errors
* @see #postProcessProperties
* @see org.springframework.beans.MutablePropertyValues
* @deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
//@Component
public class InstantiationAwareTest implements InstantiationAwareBeanPostProcessor {
//实例化之前调用的方法,如果返回了非空对象,就不再走spring自己创建逻辑。
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if(beanName.equals("people")){
return "InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation invokeed";
}
return null;
}
//实例化之后执行,但是执行的地方是在populateBean的地方
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return false;
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
return null;
}
}
首先不把它交给Spring管理,运行main方法:可以正常得到People对象。
如果把 InstantiationAwareTest上面的注解去掉再执行:直接返回 postProcessBeforeInstantiation的结果。
这是实例化之前可以进行操作的地方。
如果没有实现InstantiationAwareBeanPostProcessor接口,走spring自己实例化的逻辑
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) {
/**第二次调用后置处理器
* 创建bean实例,并将实例放在包装类BeanWrapper中返回
* 暂时先不看,设计到构造器选择,过程够讲的了
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
// 允许后置处理器修改合并后的BeanDefinition
synchronized (mbd.postProcessingLock) { //BeanDefinition中专门用于后置处理器处理时候用的锁
if (!mbd.postProcessed) {//MergedBeanDefinitionPostProcessor 被设置了
try {
// 在实例化之后,初始化之前,设置属性之前,可以通过后置处理器直接对bean的的BeanDefinition进行修改
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// 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));
}
// Initialize the bean instance. 开始初始化
Object exposedObject = bean;
try { // 在这里调用 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation了
populateBean(beanName, mbd, instanceWrapper);
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);
if (earlySingletonReference != null) {
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);
}
}
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 " +
"'getBeanNamesForType' 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;
}
上面的applyMergedBeanDefinitionPostProcessors方法:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) { //只要实现MergedBeanDefinitionPostProcessor,重写postProcessMergedBeanDefinition方法即可。
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
这里又有一个后置处理器MergedBeanDefinitionPostProcessor可以使用:第一个方法可以获取beanDefinition,对其进行修改,但是这里要注意,它调用的时候bean已经实例化了,所以对beanclass的修改已经没有用了。可以修改属性,初始化方法等。第二个方法是默认的,一般很少用,但是Spring里也用到了做一些重置清理的动作。
实现下看下效果:
//@Component
public class MergedBeanDefinitionPostProcessorTest implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
//可以改变BeanDefinition
if (beanName.equals("people")){
//可以进行属性赋值
beanDefinition.getPropertyValues().add("userName","postProcessMergedBeanDefinition");
//还可以设置初始化方法
beanDefinition.setInitMethodName("initPeople");
}
}
}
先不把它交给Spring管理,People类中有个普通的initPeople方法,和两个属性:
如果直接getPeople结果是:
放开 @Component注解运行结果:初始化方法和属性都设置成功
手动设置的初始化方法是在下面的方法中进行的。
实例化完了之后,就是填充属性,初始化,填充属性populateBean方法里面执行了,但是里面又调用了上面的提到的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation 方法。
这个方法是为了让用户在Spring 的属性填充之前可以通过构造器或工厂方法进行一些操作,这是典型的一种回调方式可以自定义字段注入到当前bean中。默认返回的结果是true,表示这个接口的下一个实现类的此方法可以继续执行,如果返回为false,此接口的实现类调用链结束。
下面就是填充属性了。从BeanDefinition中得到属性之后,又调用了一次InstantiationAwareBeanPostProcessor但是调用的是postProcessProperties。这个方法上面也有说明。具体的解析@Autowired的属性等,这里不再深入,后面单独记录。
// 是否在BeanDefinition中设置了属性值,
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
//下面的逻辑一般很少走到
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// by_name 是根据属性名字找bean
// by_type 是根据属性所对应的set方法的参数类型找bean
// 找到bean之后都要调用set方法进行注入
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;
}// 注意执行到这里,只是把属性以及找到的值存在了 pvs中,并没有完成反射赋值
// 执行完了Spring的自动注入之后,就开始解析@Autowired,这里叫做实例化回调
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 调用BeanPostProcessor 分别解析@Autowired @Value,得到属性值 这里才是调用最多属性填充的地方
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
populateBean(beanName, mbd, instanceWrapper);填充属性执行完,开始执行初始化方法。initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {// 可以暴漏三个内容给当前bean,可以让当前bean获取spring内部的一些数据
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 调用BeanPostProcessor.postProcessBeforeInitialization
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// InitializingBean afterPropertiesSet 可以让bean结合其它aware接口,在属性填充之后再次进行一些操作
// //BeanDefinition.setInitMethodName 设置的方法,在这个地方就会进行调用
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()) {
// 调用BeanPostProcessor.postProcessAfterInitialization
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
初始化结束。