一、Springboot常用注解@Configuration

 1、@Configuration注解可以标注在类的上方,标明这是一个配置类。一个配置类类似于spring中的配置文件(beans.xml)。如下MyConfig是一个配置类。springboot启动时,会生成一个MyConfig的实例对象,并将其放到IOC容器中。

同时,可以在配置类中的方法上面使用注解@Bean,springboot启动时会调动该方法,并将该方法的返回值对象放入到IOC容器中,在没有指定对象名时,该对象的名称默认就是方法名。

// @Configuration 告诉SpringBoot这是一个配置类 == 配置文件
@Configuration(proxyBeanMethods = true)
public class MyConfig {
    //给容器中添加组件。以方法名作为组件的id。
    @Bean 
    public User user01(){
        User zhangsan = new User("zhangsan", 18);
        //user组件依赖了Pet组件
        zhangsan.setPet(tomcatPet());
        return zhangsan;
    }

    // 指定组件名称
    @Bean("tom22")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}

@Configuration中有一个属性,proxyBeanMethods,默认是true。其含义是采用代理模式,即为配置类MyConfig生成一个代理对象,每次调用MyConfig的方法时,实质上是调用其代理对象的方法。

在代理模式下,每次调用MyConfig的方法获取对象时时,首先会检查IOC容器中是否已经有该对象了,如果有,就直接返回IOC容器中的已有对象,如果没有才会真正创建一个对象。所以,在代理模式下,在外部多次调用配置类方法获取的对象是同一个单实例对象。

将proxyBeanMethods为false时,关闭代理模式,每次调用MyConfig的方法都会获取一个新的对象。

测试代码如下:

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) {
        //1、返回我们IOC容器
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

        Pet tom01 = run.getBean("tom", Pet.class);
        Pet tom02 = run.getBean("tom", Pet.class);
        System.out.println("组件:"+(tom01 == tom02));

        MyConfig bean = run.getBean(MyConfig.class);
        // 代理对象com.atguigu.boot.config.MyConfig$$EnhancerBySpringCGLIB$$51f1e1ca@1654a892
        System.out.println(bean);

        //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查这个组件是否在容器中有。
        //保持组件单实例
        User user = bean.user01();
        User user1 = bean.user01();
        System.out.println(user == user1);
    }
}

当proxyBeanMethods = true时,输出如下,可以看到为MyConfig生成了一个代理对象:

 当proxyBeanMethods = false时,输出:

注意,如论是否开启代理模式,直接从IOC容器中获取对象时,获取的都是同一个对象。

而直接调用配置类的方法时,将根据代理模式是否开启而决定是否返回单实例对象。

猜你喜欢

转载自blog.csdn.net/sun_lm/article/details/120402698