SpringBoot配置@Configuration注解和@bean注解

网友投稿 307 2022-08-02


目录1.@Configuration注解2.@bean注解3.单实例4.配置类也是容器的组件5.直接调用配置类里面的person1()方法6.proxyBeanMethods——代理bean的方法

1.@Configuration注解

用法:作用在类上面 作用:告诉SpringBoot这是一个配置类,相当于Spring中的xml配置文件。

@Configuration //告诉SpringBoot这是一个配置类 == 配置文件

public class Config {

}

2.@bean注解

用法:配置类里面使用@Bean标注在方法上给IoC容器注册组件,默认也是单实例的 作用:给容器中添加组件,相当于Spring中xml配置文件中的标签。 理解:以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例

@Configuration //告诉SpringBoot这是一个配置类 == 配置文件

public class Config {

@Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例

public Person person1(){

return new Person("Mr.Yu",21,"male");

}

@Bean("customize") //id值也可以指定

public Person person2(){

return new Person("小明",20,"male");

}

}

在主程序类中打印输出我们IoC容器中的对象,看看我们的person1和customize有没有添加到容器中

@SpringBootApplication

public class MainApplication {

public static void main(String[] args) {

//1.返回我们IOC容器

ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

//2.查看容器里面的组件

String[] names = run.getBeanDefinitionNames();

for (String name : names) {

System.out.println(name);

}

}

}

输出结果:

可以看到输出结果中有我们存放进IoC容器的两个对象

3.单实例

@Bean注解存入到IoC容器中的实例也是单实例的

public static void main(String[] args) {

//1.返回我们IOC容器

ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

//2.查看容器里面的组件

String[] names = run.getBeanDefinitionNames();

for (String name : names) {

System.out.println(name);

}

//单实例

Person person1 = run.getBean("person1",Person.class);

Person person2 = run.getBean("person1",Person.class);

System.out.println("person1 == person2 :"+ (person1 == person2));

}

输出结果:

4.配置类也是容器的组件

@SpringBootApplication

public class MainApplication {

public static void main(String[] args) {

//1.返回我们IOC容器

ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

//2.查看容器里面的组件

String[] names = run.getBeanDefinitionNames();

for (String name : names) {

System.out.println(name);

}

//配置类本身也是组件

Config bean = run.getBean(Config.class);

//com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

System.out.println(bean);

}

}

输出结果:

com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

5.直接调用配置类里面的person1()方法

如果我们直接调用配置类里面的person1()方法会发生什么情http://况,它是从IoC容器中拿还是直接new一个对象呢

在new一个配置类出来的情况下,调用person1方法,它返回的是new出来的对象但是如果我们从容器中取得的配置类,无论再去掉用多少次person1方法,它始终返回的都是同一个单实例对象,也就是从IoC容器中拿的对象。

@SpringBootApplication

public class MainApplication {

public static void main(String[] args) {

//1.返回我们IOC容器

ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

//2.查看容器里面的组件

String[] names = run.getBeanDefinitionNames();

for (String name : names) {

System.out.println(name);

}

//配置类本身也是组件

Config bean = run.getBean(Config.class);

//获取到的本身就是代理对象

//com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

System.out.println(bean);

//如果我们直接调用person1方法,它是从IoC容器中拿还是直接new一个对象呢,

//在new一个配置类出来的情况下,调用person1方法,它返回的是new出来的对象

Config config = new Config();

Person person3 = config.person1();

Phttp://erson person4 = config.person1();

System.out.println("person3 == person4 :"+ (person3 == person4));

//但是如果我们从容器中取得的配置类,无论再去掉用多少次person1方法,它始终返回的都是同一个单实例对象,也就是从IoC容器中拿的对象。

//如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有;

//保持组件单实例

Person person5 = bean.person1();

Person person6 = bean.person1();

System.out.println("person5 == person6 :"+ (person5 == person6));

}

}

输出结果:

6.proxyBeanMethods——代理bean的方法

从容器中获取到的配置类对象输出结果:

com.ysw.boot.config.Config$$EnhancerBySpringCGLIB$$4aa44992@381d7219

在上述的输出结果中我们可以看到从容器中获取到的配置类对象本身就是一个被SpringCGLIB增强了的代理对象

@Configuration()默认设置的是proxyBeanMethods = true。如果@Configuration(proxyBeanMethods = true),就是代理对象调用方法。SpringBoot总会检查这个组件是否在容器中已有,调用配置类中的方法时会返回容器中已有的组件(即IoC容器中已存在的对象)。如果@Configuration(proxyBeanMethods = false),就不是代理对象调用方法,SpringBoot不会检查这个组件是否在容器中已有,调用配置类中的方法时会返回新对象。

@Configuration(proxyBeanMethods = false)

举例: 把上述5中的@Configuration()改为@Configuration(proxyBeanMethods = false)

输出结果为:

总结:

Full模式(proxyBeanMethods = true):保证每个@Bean方法被调用多少次返回的组件都是单实例的Lite模式(proxyBeanMethods = false):每个@Bean方法被调用多少次返回的组件都是新创建的组件依赖必须使用Full模式默认。其他默认是否Lite模式配置类组件之间无依赖关系用Lite模式加速容器启动过程,调用配置类中的方法时,SpringBoot每次都不会判断对象在容器中是否已经存在,减少了判断过程配置类组件之间有依赖关系,调用配置类中的方法时,SpringBoot每次都会判断对象在容器中是否已经存在,方法会被调用得到之前单实例组件,用Full模式


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringBoot中@ConfigurationProperties注解实现配置绑定的三种方法
下一篇:Java全面分析面向对象之继承(面向对象程序设计中的继承)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~