如果使用spring的方式去添加组件,则需要编写.xml文件,使用spring boot为容器添加组件就不需要编写.xml文件,我们可以直接新建一个类,并且为其添加@Configuration注解,告诉spring boot这是一个配置类,也是配置文件。如图:
此时,我们给配置类写一个方法user01,并且创建一个对象,之后为其添加一个@Bean注解 ,相当于.xml文件中的Bean标签,表示给容器添加组件。如图:
回到主程序类,可以通过getBeanDefinitionNames这个方法查看容器里面的组件,看看user01这个组件是否已经被添加到容器中。
运行主程序类,结果:
可以看到,user01组件已经被添加到容器当中了。
接下来要谈谈值得注意的事:
1、配置类里面使用@Bean标注在方法上给容器注册组件,默认是单实例的。
有关第一点,我们可以验证一下:在主程序类中多次调用组件user01的对象,并且判断对象user1是否等于对象user2。如图:
运行主程序类,结果:
可以看到user1 == user2其结果为true,第一点证明成功,确实是单实例。
2、配置类本身也是组件(通过getBeanDefinitionNames方法可以看到使用@Bean标注的方法名称,此外也一样能看到使用@Configuration标注的配置类名称)。还是这张图:
在这张图上我们可以得到两个重要的信息,第一就是 @Configuration注解,意为这个类是配置类;第二就是这个配置类名称为MyConfig。现在通过getBeanDefinitionNames这个方法查看容器里面的组件,看看MyConfig是否已经被添加到容器中。如图:
答案是显而易见的,在容器中,配置类本身也是一个组件。
3、在spring boot2.0及以后,@Configuration里面多了一个注解@proxyBeanMethods(意为代理Bean的方法),默认为true。
重点在于第三点,它引出了spring boot底层注解@Configuration的两种配置:
full(全配置) 和 lite(轻量级配置)
当@proxyBeanMethods为true时,@Configuration就是full配置。即配置类组件之间有依赖关系,方法会被调用得到之前的单实例组件。简单来说就是某个对象可能需要用到另一个对象,这就叫存在依赖关系。full配置每次启动都要检查是否存在单实例对象,会降低运行速度,但组件之间存在依赖关系时一定要用full配置。
关于依赖关系,举个例子:我们在实体类User中调用另一个实体类Pet,并生成getter、setter和toString方法,如图:
我们再在配置类MyConfig中的user01方法做一些小小的改动,使其可以调用tomcatPet方法,如图:
注意:此时我的proxyBeanMethods是为true的。
回到主程序类,我们从容器中获取user01和tomcatPet两个组件,并且进行判断,如图:
运行之后结果:
也就是说我在组件user01里面调用的tomcatPet对象和 组件tomcatPet中的对象是一样的,可以说是User组件依赖了Pet组件。所以当@proxyBeanMethods为true时,外部无论对配置类中的这个组件注册的方法调用多少次获取的都是之前注册到容器中的单实例对象。
当@proxyBeanMethods为false时,@Configuration就是lite配置。配置类组件之间无依赖关系时用Lite模式加速容器启动过程,减少判断,可以加快启动速度。
我们把@proxyBeanMethods为true改成@proxyBeanMethods为false,再运行,如图:
可以看到组件user01里面调用的tomcatPet对象和组件tomcatPet中的对象是不一样的,也就是说user01虽然调用了tomcatPet,但是是新生成的,和tomcatPet的对象不是同一个。即外部对配置类中的组件调用一次,就new一个对象。