4.@configuration注解(标明当前类是springboot的配置类)
1.spring注册bean组件:使用的是配置进行注册
2.springboot注册bean组件:使用的是@configuration配置类的方式
1.配置类:(
1.配置类中使用@Bean标注在方法上给容器注册组件,默认是单实例的
2.配置类本身也是组件
3.外部无论对配置类中的组件的注册方法(Person01()/dog01())获取的都是之前注册在容器中的单实例(即使通过Myconfiguration该组件直接调用方法)
)
//告诉springboot这是一个配置类==配置文件
@Configuration
public class Myconfiguration {
/**
* 给容器中添加组件
* 1.以方法名作为组件的id
* 2.返回类型就是组件的类型
* 3.返回值就是组件在容器中的实例
*/
@Bean
public Person person01(){
return new Person("吴孟达",18);
}
@Bean("dog")-->可以指定bean的name
public Dog dog01(){
return new Dog("刘丹",18);
}
}
3.@configuration标签详解
1.springboot 2有个最新的变化,@Configuration标签中添加了boolean proxyBeanMethods() default true;
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;---->springboot2添加了是否是代理对象方法的设置
}
2.下面针对@Configuration中proxyBeanMethods的true/false来进行讨论
2.1 当设置proxyBeanMethods=false时,获取到的对象不是代理对象
@Configuration(proxyBeanMethods = false)
public class Myconfiguration {
@Bean
public Person person01(){
return new Person("吴孟达",18);
}
@Bean
public Dog dog01(){
return new Dog("刘丹",18);
}
}
2.2 启动类代理如下:
@SpringBootApplication(scanBasePackages = "com.atguigu")
public class MainApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
Myconfiguration myconfiguration = run.getBean("myconfiguration", Myconfiguration.class);----->
Myconfiguration myconfiguration1 = run.getBean("myconfiguration", Myconfiguration.class);---->这两个获取到的配置类对象是同一对象,但不是代理对象
System.out.println(myconfiguration);
System.out.println(myconfiguration1);
Person person01 = myconfiguration.person01();
Person person02 = myconfiguration.person01();
System.out.println(person01==person02);---->但当设置proxyBeanMethods=false时,每次获取到的对象都是新对象
}
}
输出:
com.atguigu.boot.configuration.Myconfiguration@78c7f9b3
com.atguigu.boot.configuration.Myconfiguration@78c7f9b3
false
2.3 如果当proxyBeanMethods=true时,
输出:
com.atguigu.boot.configuration.Myconfiguration$$EnhancerBySpringCGLIB$$56efdd6c@27e32fe4
com.atguigu.boot.configuration.Myconfiguration$$EnhancerBySpringCGLIB$$56efdd6c@27e32fe4
true
发现:每次获取到的配置类对象是代理对象,并且每次执行配置类中的方法获取到的组件都是同一组件
3.结论:
1. 当proxyBeanMethods = false时,获取到的配置类对象不是代理对象,每次执行获取组件方法时,不会检查容器中是否有该组件,每次都执行方法!
2. 当proxyBeanMethods = true时,获取到的对象是代理对象,每次执行获取组件方法时,都会检查容器中是否有该组件,如果有的话会直接获取不会重新创建,没有的话会直接创建!