类加载、初始化区别
类的加载是一个过程,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。初始化只是其中一个很重要的阶段。
Bean和Spring容器的关系
工作原理:
(1)spring容器会根据含有Bean配置的XML文件(spring.xml),把配置文件的Bean配置信息与spring容器中Bean定义注册表相对应起来;
(2)spring容器根据Bean注册表实例化Bean;
(3)通过Bean的实现类,把实例化过的Bean放到spring容器中的Bean缓存池中;
(4)某个模块要是使用的话,通过注解或者xml配置,让spring把Bean缓存池中的实例Bean注入到该模块当中;
Spring Bean注入方式
bean注入方式:
- 通过XML来配置的,分别有属性注入、构造函数注入和工厂方法(静态工厂、实例工厂)注入;
- 通过注解的方式注入,组件扫描+@Autowired和@Resource
- 注解类+@Bean
属性注入、构造方法注入区别:
- 使用构造函数依赖注入时,Spring保证当前对象所有依赖的对象先实例化后,才实例化这个对象(没有他们就没有我原则)
- 使用set方法依赖注入时,Spring首先实例化当前对象,然后才实例化所有依赖的对象。
@Autowired和@Resource的区别
- @Resource注解是由J2EE提供,而@Autowired是由spring提供
- @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在如果允许为null,可以设置它required属性为false,如果想按照名称来转配注入,则需要结合@Qualifier一起使用;
- @Resource默认按照名称装配,当找不到与名称匹配的bean才会按照类型装配,可以通过name属性指定,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找 依赖对象.注意:如果没有指定name属性,并且按照默认的名称仍然找不到依赖的对象时候,会回退到按照类型装配,但一旦指定了name属性,就只能按照名称装配了.
Spring Bean的作用域
Spring IOC容器创建一个Bean实例时,可以为Bean指定实例的作用域,作用域包括singleton(单例模式)、prototype(原型模式)、request(HTTP请求)、session(会话)、global-session(全局会话)
spring中的单例模式和设计模式中的单例模式的区别
spring单例bean与设计模式的单例模式的区别在于它们关联的环境不一样。单例模式是指在一个JVM进程中仅有一个实例,无论在程序中何处获取该实例,始终都返回同一个对象。而spring单例是指一个spring bean容器(ApplicationContext)中仅有一个实例。spring的单例bean是与其容器密切相关的,如果在一个JVM进程中有多个spring容器,即使是单例bean,也一定会创建多个实例,
循环依赖问题
1.什么是循环依赖?
例:类A持有属性类B,类B持有属性类C,类C又持有属性类A
2.循环依赖时BeanCurrentlyInCreationException异常原因?
Spring容器会将每一个正在创建的Bean标识符放在一个“当前创建Bean池”中,Bean标识符在创建过程中将一直保持在这个池中,因此如果在创建Bean过程中发现自己已经在“当前创建Bean池”里时将抛出BeanCurrentlyInCreationException异常表示循环依赖;而对于创建完毕的Bean将从“当前创建Bean池”中清除掉。
3.循环依赖时对象创建过程?
Spring容器先创建单例StudentA,StudentA依赖StudentB,然后将A放在“当前创建Bean池”中,此时创建StudentB,StudentB依赖StudentC ,然后将B放在“当前创建Bean池”中,此时创建StudentC,StudentC又依赖StudentA, 但是,此时Student已经在池中,所以会报错,因为在池中的Bean都是未初始化完的,所以会依赖错误.
4.如何解决循环依赖问题?
可以用setter注入的方式,Spring是先将Bean对象实例化之后,再设置对象属性。所以会先调用他的无参构造函数实例化。每个对象存在一个map中。当遇到依赖,就去map中调用对应的单例对象。
基于此:对于“prototype”作用域Bean,Spring容器无法完成依赖注入,因为“prototype”作用域的Bean,Spring容器不进行缓存,因此无法提前暴露一个创建中的Bean。基于构造函数的注入,如果有循环依赖,Spring也是不能够解决的
流程图大致为:
doGetBean过程
这个方法主要做了以下工作:
- 转换对应beanName: 例如别名转为实名
- 尝试从缓存加载单例:这里加载出来的可能只是一个没有完全实例化的singleton bean (为了解决循环依赖问题)
- 转化工厂Bean取出来的代理bean为真正的bean,单例bean到这一步就可以返回了。【注:无论是缓存中取出的bean还是后续创建的bean,都有可能是通过工厂Bean(FactoryBean)创建的代理对象,还不是真正需要的bean,需要执行一个重要的方法getObjectForBeanInstance()才能获取真正的bean。这个方法出现频率很高,很多地方都需要用到,因为spring中有很多FactoryBean(注意区分BeanFactory)】
- 后处理器入口。即上面的getObjectForBeanInstance() 不仅仅是完成了FactoryBean()获取bean的工作,对于由FactoryBean创建的prototy bean还会执行用户定义的postProcessObjectFromFactoryBean()中的操作,这也是个非常重要的spring扩展接口。
- 检查protorype模式下是否存在循环依赖,是则抛异常 (只有单例模式允许循环依赖)
- 如果缓存没有数据就转到父类工厂去加载(就是扩大搜索范围)
- 将存储XML中配置信息的GernericBeanDefinition转为RootBeanDefinition供后续处理
- 加载依赖的bean:这是个递归调用。 Spring在初始化bean前,总是先初始化依赖的bean
- 通过Java反射的方式,开始按scope类别创建bean (默认singleton,可配置prototype, request之类)
- 上面的创建bean之前,处理bean中override-method属性,即针对 lookup-method和replace-method做的处理,动态地为当前bean生成代理并使用对应拦截器为bean做增强处理。
- 对BeanDefinigitionz中的属性做前置处理。也就是InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation()和postProcessAfterInitialization()在此处生效。经过后处理器后可能已经不是原来的bean,而是代理bean了。
- 实例化bean前先检查是否需要使用cglib动态增强,即是否要对lookup或者replace-method做处理,是的话返回的就是代理对象。
- 检查是否要将正在实例化的bean提前曝光(解决单例循环依赖),是则加入
- 属性注入。注入方式有 antowireByName(按bean name在容器中查找并注入), autowireByType
- 调用BeanPostProcessor的后处理器(在客户调用客户自定义初始化方法前后,都会执行BeanPostProcessor中的方法)增强bean
- 若bean实现了Initializing接口,此时会调用其中重写的afterPropertiesSet方法。
- 调用自定义 init-method方法。
- 注册DisposableBean,即销毁bean方法的扩展。至此,已经实例化bean,即create的过程结束
- 类型转换,上面的doGetBean()会传入一个要求转换的类型,一般为Class<?>
spring中BeanFactory和FactoryBean的区别
1、BeanFactory
BeanFactory定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口,也就是Spring IOC所遵守的最底层和最基本的编程规范。
它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
在Spring代码中,BeanFactory只是个接口,并不是IOC容器的具体实现,
但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某种功能的实现。
2、FactoryBean
一般情况下,Spring通过反射机制利用<bean>的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,
如果按照传统的方式,则需要在<bean>中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。
Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。
FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。
它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean<T>的形式
创建Bean
准备阶段:createBean():
1 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
2 if (logger.isDebugEnabled()) {
3 logger.debug("Creating instance of bean '" + beanName + "'");
4 }
5 // 确保此时实际解析了bean类
6 //-----------------------------------------------方法1-----------------------------------------------//
7 resolveBeanClass(mbd, beanName);
8 //-----------------------------------------------方法1-----------------------------------------------//
9 // Prepare method overrides.
10 try {
11 mbd.prepareMethodOverrides();
12 }
13 catch (BeanDefinitionValidationException ex) {
14 throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
15 beanName, "Validation of method overrides failed", ex);
16 }
17
18 try {
19 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
20 //-----------------------------------------------方法2-----------------------------------------------//
21 //如果bean实现了实例化前处理器接口的,则需要在实例化之前调用这个方法
22 //bean的生命周期的中实现了InstantiationAwareBeanPostProcessor会在这里调用实现的postProcessBeforeInstantiation
23 Object bean = resolveBeforeInstantiation(beanName, mbd);
24 //-----------------------------------------------方法2-----------------------------------------------//
25 if (bean != null) {
26 return bean;
27 }
28 }
29 catch (Throwable ex) {
30 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
31 "BeanPostProcessor before instantiation of bean failed", ex);
32 }
33 //-----------------------------------------------方法3-----------------------------------------------//
34 Object beanInstance = doCreateBean(beanName, mbd, args);
35 //-----------------------------------------------方法3-----------------------------------------------//
36 if (logger.isDebugEnabled()) {
37 logger.debug("Finished creating instance of bean '" + beanName + "'");
38 }
39 return beanInstance;
40 }
View Code
真正的创建Bean:doCreateBean():
doCreateBean方法代码:
1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
2 // Instantiate the bean.
3 //BeanWrapper提供设置和获取属性值(单独或批量),获取属性描述符和查询属性以确定它们是可读还是可写的功能
4 BeanWrapper instanceWrapper = null;
5 //如果RootBeanDefinition是单例的,则移除未完成的FactoryBean实例的缓存
6 if (mbd.isSingleton()) {
7 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
8 }
9 if (instanceWrapper == null) {
10 //创建bean实例
11 //------------------------------------------方法1----------------------------------------//
12 instanceWrapper = createBeanInstance(beanName, mbd, args);
13 //------------------------------------------方法1----------------------------------------//
14 }
15 //获取BeanWrapper中封装的Object对象,其实就是bean对象的实例
16 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
17 //获取BeanWrapper中封装的bean的Class
18 Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
19
20 // Allow post-processors to modify the merged bean definition.
21 synchronized (mbd.postProcessingLock) {
22 if (!mbd.postProcessed) {
23 //--------------------------------------------------2---------------------------------------------//
24 ////bean 的生命周期之一。如果实现了MergedBeanDefinitionPostProcessor会在这里调用postProcessMergedBeanDefinition方法
25 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
26 //--------------------------------------------------2---------------------------------------------//
27 mbd.postProcessed = true;
28 }
29 }
30
31 // Eagerly cache singletons to be able to resolve circular references
32 // even when triggered by lifecycle interfaces like BeanFactoryAware.
33 //如果RootBeanDefinition是单例的,并且开启了自动尝试解析bean之间的循环引用,并且当前bean正在创建中,则说明这个bean需要被加入到缓存的单例bean集合中
34 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
35 isSingletonCurrentlyInCreation(beanName));
36 if (earlySingletonExposure) {
37 if (logger.isDebugEnabled()) {
38 logger.debug("Eagerly caching bean '" + beanName +
39 "' to allow for resolving potential circular references");
40 }
41 /**
42 * addSingletonFactory会将beanName和ObjectFactory对象作为键值对保存到缓存的单例集合中
43 * singletonObjects: 单例对象的缓存 ConcurrentHashMap
44 * singletonFactories:单例工厂的缓存 HashMap
45 * earlySingletonObjects: 早期单例对象的缓存 HashMap
46 * registeredSingletons: 一组已经注册的单例,按注册顺序排序 LinkedHashSet
47 */
48 addSingletonFactory(beanName, new ObjectFactory<Object>() {
49 public Object getObject() throws BeansException {
50 //---------------------------------------------3------------------------------//
51 return getEarlyBeanReference(beanName, mbd, bean);
52 //---------------------------------------------3------------------------------//
53 }
54 });
55 }
56 // Initialize the bean instance.
57 Object exposedObject = bean;
58
59 try {
60 //---------------------------------------------4------------------------------//
61 //进行属性填充
62 populateBean(beanName, mbd, instanceWrapper);
63 //---------------------------------------------4------------------------------//
64 if (exposedObject != null) {
65 //---------------------------------------------5------------------------------//
66 //初始化给定的bean实例,应用工厂回调以及init方法和bean后处理器
67 exposedObject = initializeBean(beanName, exposedObject, mbd);
68 //---------------------------------------------5------------------------------//
69 }
70 }
71 catch (Throwable ex) {
72 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
73 throw (BeanCreationException) ex;
74 }
75 else {
76 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
77 }
78 }
79 //如果单例bean已经缓存了,则直接获取
80 if (earlySingletonExposure) {
81 Object earlySingletonReference = getSingleton(beanName, false);
82 if (earlySingletonReference != null) {
83 if (exposedObject == bean) {
84 exposedObject = earlySingletonReference;
85 }
86 //如果不允许在循环引用的情况下使用注入原始bean实例(即使注入的bean最终被包装),并且依赖的bean列表中存在需要创建bean。这时候就说明存在循环依赖
87 else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
88 //根据beanName获取所有依赖的bean的beanName
89 String[] dependentBeans = getDependentBeans(beanName);
90 Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
91 for (String dependentBean : dependentBeans) {
92 //删除存在循环依赖的bean
93 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
94 actualDependentBeans.add(dependentBean);
95 }
96 }
97 if (!actualDependentBeans.isEmpty()) {
98 throw new BeanCurrentlyInCreationException(beanName,
99 "Bean with name '" + beanName + "' has been injected into other beans [" +
100 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
101 "] in its raw version as part of a circular reference, but has eventually been " +
102 "wrapped. This means that said other beans do not use the final version of the " +
103 "bean. This is often the result of over-eager type matching - consider using " +
104 "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
105 }
106 }
107 }
108 }
109
110 // Register bean as disposable.
111 try {
112 //将给定的bean添加到此一次性Bean列表中,这个列表中的bean在Spring关闭的时候会查询里面的bean,并调用实现的销毁方法(包含实现了DisposableBean接口的方法和自定义的destory方法),满足其中一个条件
113 // 1.实现了DisposableBean接口
114 //2.自定义了destroy方法
115 //3.实现了AutoCloseable接口
116 registerDisposableBeanIfNecessary(beanName, bean, mbd);
117 }
118 catch (BeanDefinitionValidationException ex) {
119 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
120 }
121
122 return exposedObject;
123 }
实例化Bean,createBeanInstance:
1 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
2 //获取RootBeanDefinition的Class属性
3 Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
4 //如果bean的类修饰符不是public则报错
5 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
6 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
7 } else {
8 Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
9 if (instanceSupplier != null) {
10 //如果定义了Supplier函数,则调用Supplier的get方法获取实例化对象
11 return this.obtainFromSupplier(instanceSupplier, beanName);
12 } else if (mbd.getFactoryMethodName() != null) {
13 //查看RootBeanDefinition的factor-method属性是不是空的,不为空说明bean的实现要通过先实例化对应的factoryBean
14 // 然后调用factoryMethod方法实现,或者直接调用静态的factoryMethod方法
15 return this.instantiateUsingFactoryMethod(beanName, mbd, args);
16 } else {
17 //重新创建同一个bean时相关的判断条件
18 boolean resolved = false;
19 boolean autowireNecessary = false;
20 if (args == null) {
21 synchronized(mbd.constructorArgumentLock) {
22 //如果缓存的已解析的构造函数或工厂方法对象不为空,则说明这是重新创建同一个bean
23 if (mbd.resolvedConstructorOrFactoryMethod != null) {
24 resolved = true;
25 autowireNecessary = mbd.constructorArgumentsResolved;
26 }
27 }
28 }
29
30 //如果是重新创建,就直接创建
31 if (resolved) {
32 //如果构造函数参数标记是已解析,就直接进行构造,否则重新解析然后创建
33 return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
34 } else {
35 //如果不是重新创建的bean,需要确定要用于构造bean的候选构造函数,检查所有已注册的构造函数
36 //bean 的生命周期之一,如果实现了SmartInstantiationAwareBeanPostProcessor接口,会在这里调用determineCandidateConstructors方法
37 Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
38 return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? this.instantiateBean(beanName, mbd) : this.autowireConstructor(beanName, mbd, ctors, args);
39 }
40 }
41 }
42 }
实例化Bean,populateBean方法:
1 protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
2 //如果BeanWrapper为null说明bean没有实例化成功,会报错
3 if (bw == null) {
4 if (mbd.hasPropertyValues()) {
5 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
6 }
7 } else {
8 //为任何实现了InstantiationAwareBeanPostProcessors接口的方法,提供在设置属性之前修改bean状态的机会,就是实例化bean的时候(不是赋值的时候)
9 boolean continueWithPropertyPopulation = true;
10 if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
11 Iterator var5 = this.getBeanPostProcessors().iterator();
12
13 while(var5.hasNext()) {
14 BeanPostProcessor bp = (BeanPostProcessor)var5.next();
15 if (bp instanceof InstantiationAwareBeanPostProcessor) {
16 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
17 //调用实现的postProcessAfterInstantiation方法
18 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
19 continueWithPropertyPopulation = false;
20 break;
21 }
22 }
23 }
24 }
25
26 if (continueWithPropertyPopulation) {
27 PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
28 if (mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
29 //深拷贝RootBeanDefinition的所有的属性值。保证PropertyValue引用是独立的,但它不能深度复制当前由各个PropertyValue对象引用的对象
30 MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
31 //按照按名称注入的方式注入
32 if (mbd.getResolvedAutowireMode() == 1) {
33 this.autowireByName(beanName, mbd, bw, newPvs);
34 }
35
36 //按照按名称类型的方式注入
37 if (mbd.getResolvedAutowireMode() == 2) {
38 this.autowireByType(beanName, mbd, bw, newPvs);
39 }
40
41 pvs = newPvs;
42 }
43
44 boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
45 boolean needsDepCheck = mbd.getDependencyCheck() != 0;
46 //如果bean实现了InstantiationAwareBeanPostProcessor接口或者bean需要进行依赖检查,需要进行处理
47 if (hasInstAwareBpps || needsDepCheck) {
48 if (pvs == null) {
49 pvs = mbd.getPropertyValues();
50 }
51
52 PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
53 //一次调用实现的InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法
54 if (hasInstAwareBpps) {
55 Iterator var9 = this.getBeanPostProcessors().iterator();
56
57 while(var9.hasNext()) {
58 BeanPostProcessor bp = (BeanPostProcessor)var9.next();
59 if (bp instanceof InstantiationAwareBeanPostProcessor) {
60 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
61 pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
62 if (pvs == null) {
63 return;
64 }
65 }
66 }
67 }
68
69 //进行依赖检查,主要检查设置到bean中的数据类型和对象是否个bean对象自身定义的数据类型和对象是不是一样
70 if (needsDepCheck) {
71 this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
72 }
73 }
74
75 if (pvs != null) {
76 //属性填充
77 this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
78 }
79
80 }
81 }
82 }
实例化Bean,initializeBean方法
1 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
2 //如果bean是BeanNameAware,BeanClassLoaderAware或者BeanFactoryAware其中某一个的实现类就需要进行处理
3 if (System.getSecurityManager() != null) {
4 AccessController.doPrivileged(new PrivilegedAction<Object>() {
5 public Object run() {
6 invokeAwareMethods(beanName, bean);
7 return null;
8 }
9 }, getAccessControlContext());
10 }
11 else {
12 invokeAwareMethods(beanName, bean);
13 }
14
15 Object wrappedBean = bean;
16 //bean的生命周期之一。如果实现了BeanPostProcessor接口则在这里调用postProcessBeforeInitialization方法
17 if (mbd == null || !mbd.isSynthetic()) {
18 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
19 }
20 //bean的生命周期之一,如果实现了InitializingBean接口,会在这里调用实现的afterPropertiesSet方法
21 try {
22 invokeInitMethods(beanName, wrappedBean, mbd);
23 }
24 catch (Throwable ex) {
25 throw new BeanCreationException(
26 (mbd != null ? mbd.getResourceDescription() : null),
27 beanName, "Invocation of init method failed", ex);
28 }
29 //bean的生命周期之一。如果实现了BeanPostProcessor接口则在这里调用postProcessAfterInitialization方法
30 if (mbd == null || !mbd.isSynthetic()) {
31 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
32 }
33 return wrappedBean;
34 }
View Code