0
点赞
收藏
分享

微信扫一扫

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解

为了后面深入理解Springboot的自动配置的原理。我们先学习几个注解。

先准备好两个java bean:

根据前面讲的:

因为启动类:com.rtl.boot.MainApplication在这里

所以其他组件应该在com.rtl.boot包下面或者子包下面。

所以:

我们在com.rtl.boot包下新建一个包bean

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_springboot2


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_spring_02


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_spring_03


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_springboot2_04

以前:需要把这两个bean类添加到容器里面的方式:

在resources里面新建配置文件bean.xml

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_05


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_spring_06


然后再里面写bean标签进行注册:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_07


现在springboot如何给容器中添加组件呢?

方式1:

使用注解@Configuration

在com.rtl.boot下面,写一个类叫做config.MyConfig

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_springboot2_08


给这个类的类体上写@Configuration

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_springboot2_09


@Configuration这个注解就是告诉Springboot这个类是一个配置类。然后再这个配置类里面写方法:

方法的

1、方法名:就是组件的id

2、返回值类型:就是组件类型

3、返回值:就是组件在容器里面的实例对象。

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_10


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_11

和写配置文件效果一样:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_07

然后再主程序里面打印我们目前容器里面的组件。

测试看看有没有生成User和Pet

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_13


运行之后就打印了非常多的组件名字:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_14


搜索:user01,找到了:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_15


搜索:cat

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_spring_16

这个是默认使用方法名来作为组件id。

如果不想使用方法名作为组件id。

那你就需要添加@Bean注解的属性:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_17


再次运行:

现在搜索cat就没有了。而要搜索tom:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_18

默认这种方式配置的组件,都是单实例的。

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_19


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_20

总结:

1、配置类的类体加@Configuration注解,这个配置类里面的方法使用@Bean注解,这种方式就可以给容器注册这个组件了。默认都是单实例的。

2、配置类MyConfig本身也已经在容器里面了。也是组件。

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_21


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_springboot2_22

3、在注解Configuration里面有一个属性是Springboot1里面没有的。

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_springboot2_23


这个属性:proxyBeanMethods

默认值是true。

这是个什么呢?

代理bean的方法。测试情况1:

通过配置类对象调用方法 获取组件,问:多次获取的组件是单实例的吗?

1、拿到配置类对象:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_24

//1、这就是返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、通过IOC容器拿到配置类对象
MyConfig myConfig = run.getBean(MyConfig.class);

2、通过配置类对象调用cat方法获取Pet的对象。

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_25


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_spring_26

查看这种方式得到的myConfig对象和是否单实例?

配置对象是增强代理对象,也是单实例

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_单实例_27

通过配置类对象调用方法 获取组件,问:多次获取的组件是单实例的吗?答案是:同一个对象。

结论:这种方式获取容器里面的对象都是单实例的。

这种方式获取对象和之前是不一样的。虽然之前也是单实例的。

之前第一种获取的形式:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_19


现在第2种获取:通过配置类对象调用方法获取。第二种方式获取,之所以也是单实例的,就是因为@Configuration注解里面有参数proxyBeanMethods,且默认值为true。

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_29


那如果第二种方式获取对象,我们设置注解@Configuration的属性proxyBeanMethods为false呢?

测试情况2:

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_springboot2_30


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_31


学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_类对象_32


发现,如果:

@Configuration(proxyBeanMethods = false)

那么配置类就不是增强代理对象了。而就是本身。

同时,获取的对象也不是单实例的。

总结:

//单实例,全模式 Full
@Configuration(proxyBeanMethods = true)

//多实例,轻量级模式   Lite
@Configuration(proxyBeanMethods = false)

这两个模式就很好的解决了组件之间的依赖问题。
调成false的优点就是:
Springboot不会来检查方法user01返回的User对象在容器有没有,跳过检查,这样Springboot启动就会比较快。

如果是true的话:
每一个调用方法user01,都会检查容器中是否有,这样就很慢。

这个设置为true还是false的使用场景:
1、如果组件之间没有依赖关系,那就使用false,轻量级。

2、如果组件之间有依赖关系,比如User类里面有个属性是Pet,也就是User组件依赖Pet,那为了保证User拿属性值的时候就是从容器里面去拿,而不是去外面拿,所以需要使用true Full模式。去扫描组件。

学习springboot2的第3天(2021-12-02)08-底层注解-@Configuration详解_spring_33


举报

相关推荐

0 条评论