spring @Configuration注解的proxyBeanMethods属性

 

写在前面的话

或许大家都知道@Configuration注解与@Component注解的区别,@Component注解用来定义一个Bean,而@Configuration与@Bean注解结合,可以在一个类中定义多个Bean

最近我发现@Configuration注解有一个属性proxyBeanMethods,很想知道这个属性的作用,所以就研究了一下

 

1、@Configuration注解的原理

首先来看一下@Configuration注解的源码:

package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
	@AliasFor(annotation = Component.class)
	String value() default "";
	boolean proxyBeanMethods() default true;

}

 

发现@Configuration注解上打了一个@component注解

spring会扫描所有@component注解的类及其子类(包括@Configuration注解声明的类),认为这些类是bean, 并且把这些bean对应的beanDefinition放到容器中进行管理。BeanDefinition是对bean的描述,里边存有bean的名称,Class等基本信息

在获取到所有的bean defenition之后,Spring会有一些post process执行,其中一个就是ConfigurationClassPostProcessor, 在这里,Spring会遍历所有的bean definition, 如果发现其中有标记了@Configuration注解的,会对这个类进行CGLIB代码,生成一个代理的类,并且把这个类设置到BeanDefenition的Class属性中。当需要拿到这个bean的实例的时候,会从这个class属性中拿到的Class对象进行反射,那么最终反射出来的是代理增强后的类

代理中对方法进行了增强?在哪方面进行了增强?对于@Bean标记的方法,返回的都是一个bean,在增强的方法中,Spring会先去容器中查看一下是否有这个bean的实例了,如果有了的话,就返回已有对象,没有的话就创建一个,然后放到容器中

 

2、@Configuration注解的proxyBeanMethods属性

基于上面的@Configuration注解的原理,下面来研究一下proxyBeanMethods这个属性

下面是测试proxyBeanMethods属性作用的代码:

import com.bobo.group.springbootcommonbase.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class CommonConfig {
    @Bean
    public User user1(){
        user2();
        return new User(1,"root","ok");
    }
    @Bean
    public User user2(){
        System.out.println("user2被调用");
        return new User(2,"admin","ok");
    }

}

 

proxyBeanMethods默认为true,表示cglib会为@Configuration生成一个代理类,因此而在user1中调用user2方法时,会通过代理方法从IOC容器中去获取,这样就是单例的。运行的时候,控制台只打印了一次“user2被调用”就证明了这一点
但是如果将proxyBeanMethods设为false,则表示不生成代理,那么user1中调用user2,会再生成一个对象而不是从IOC容器中获取,这样能提高性能,也造成了多例。运行时控制台会打印两次“user2被调用”,如下图所示。

 

 

 

 

 

 

 

 

 

 

 

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波波老师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值