Configuration 的 proxyBeanMethods 属性与 Bean 方法
@Configuration
的 proxyBeanMethods
属性与 @Bean
方法
@Configuration
注解所标注的配置类中,我们常常使用 @Bean
标注来方法向 IoC 容器中注册组件。
@Configuration
的 proxyBeanMethods
属性用来控制是否对 @Bean
方法进行代理。
如果
proxyBeanMethods = true
,那么 Spring 会将@Configuration
所标注的配置类作为目标类来生成相应的代理类,最后将代理类注册到容器中。类中的
@Bean
方法均被加上一层代理,此时向 IoC 容器中注册组件的具体逻辑,是在@Bean
方法的代理的后置增强中完成。无论是 Spring 为了注册组件去调用
@Bean
方法,还是用户代码中去主动调用@Bean
方法,所调用的都是代理方法,需要经过增强代码处理。前置增强:尝试从 IoC 容器中获取类型为
@Bean
方法返回值类型的对象,如果能够获取到,则直接返回 IoC 容器中的相应对象,如果获取不到执行目标方法。目标方法:就是我们自己编写的
@Bean
方法中的内容,它负责创建一个新对象然后返回后置增强:获取到目标方法的返回值以后,将该新对象注册到 IoC 容器中。
如果
proxyBeanMethods = false
,那么 Spring 会将@Configuration
所标注的配置类直接注册到容器中。类中的
@Bean
方法此时无代理,此时向 IoC 容器中注册组件的具体逻辑,是在 Spring 中另外一块代码来完成。无论是 Spring 为了注册组件去调用
@Bean
方法,还是用户代码中去主动调用@Bean
方法,都是直接创建新对象返回。只不过 Spring 为了注册去调用的话,得到返回值以后还需要将该返回值注册到 IoC 容器中。
proxyBeanMethods = true
+ 组件依赖的情况下,Spring 调用 @Bean
方法进行组件注册的流程
1 |
|
Spring 会顺序扫描 @Configuration
所标注的 MyConfig
类中的 @Bean
方法并进行调用,所以 Spring 会先调用 user01()
,然后再调用 tomcatPet()
。
- Spring 调用
user01()
来进行组件注册,该方法已被代理,代理发现 IoC 容器中目前还没有User
对象,所以接下来会执行目标user01()
方法 - 执行目标
user01()
方法,在内部新创建了一个User
对象命名为zhangsan
,然后在执行zhangsan.setPet(tomcatPet())
时,转而去调用tomcatPet()
方法。 tomcatPet()
方法也是@Bean
方法,因此先经过代理,代理发现,IoC 容器中目前还没有Pet
对象,所以接下来会执行目标tomcatPet()
方法- 执行目标
tomcatPet()
方法,创建了一个Pet
对象并返回,代理的后置增强将该新Pet
对象注册到 IoC 容器中,然后继续返回。 zhangsan.setPet(tomcatPet())
将返回的Pet
对象设置到zhangsan
的属性中,然后user01()
目标方法执行结束并返回一个User
对象,代理的后置增强,将该新User
对象注册到 IoC 容器中。- Spring 调用
tomcatPet()
来进行组件注册,该方法已被代理,代理发现 IoC 容器中已存在Pet
对象,因此直接返回。
proxyBeanMethods = false
+ 组件依赖的情况下,Spring 调用 @Bean
方法进行组件注册的流程
1 |
|
Spring 会顺序扫描 @Configuration
所标注的 MyConfig
类中的 @Bean
方法并进行调用,所以 Spring 会先调用 user01()
,然后再调用 tomcatPet()
。
- Spring 调用
user01()
来进行组件注册,方法无代理可直接执行,方法内部创建了一个User
对象并命名为zhangsan
,然后在执行zhangsan.setPet(tomcatPet())
时,转而去调用tomcatPet()
方法。 tomcatPet()
方法无代理可直接执行,创建一个Pet
对象并返回。zhangsan.setPet(tomcatPet())
将返回的Pet
对象设置到zhangsan
的属性中,然后user01()
方法执行结束并返回一个User
对象。- Spring 将返回的
User
对象注册到 IoC 容器中。 - Spring 调用
tomcatPet()
来进行组件注册,方法无代理可直接执行,方法内部创建了一个Pet
对象并返回。 - Spring 将返回的
Pet
对象注册到 IoC 容器中。