SpringBoot注解_@Configuration与@Bean

底层注解@Configuration

/*
* @Configuration:
*           1、标注该类是一个配置类,告诉springboot这个一个配置类
*           2、配置类相当于spring中的xml配置文件
*
* 打√号的叶子可以看到当前配置类中注入了多少个组件,配置类叶子中的组件id默认首字母是小写
*
* 带有c和▷的叶子可以看到与当前配置类有关的依赖类关系
* 带有c和▷的叶子的配置类类似于一个小型容器
* */
@Configuration
public class MyConfig {

    @Bean("User01") 
    public User User01(){
        return new User("zhangsan",18);
    }

    @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}
  • 打√号的叶子可以看到当前配置类中注入了多少个组件,配置类叶子中的组件id默认首字母是小写

    SpringBoot注解_@Configuration与@Bean_第1张图片

  • 带有c和▷的叶子可以看到与当前配置类有关的依赖类关系、 带有c和▷的叶子的配置类类似于一个小型容器

SpringBoot注解_@Configuration与@Bean_第2张图片

SpringBoot注解_@Configuration与@Bean_第3张图片

SpringBoot注解_@Configuration与@Bean_第4张图片

底层注解@Bean

@Configuration
public class MyConfig {

    /*
     * @Bean:
     *      1、给容器中添加组件      
     *      2、方法名为组件的id     
     *      3、返回类型为组件类型     
     *      4、返回的值就是spring容器中存放的该类实例对象      
     *      
     * 组件 => 抽象数据类型(是个概念)         
     * 方法名 => 实例的名字
     * 返回类型 => 组件具体类型
     * 返回值 => 抽象数据类型的实例
     *
     * Bean注解可以自定义对象名字,对象名字 == 实例名字 == 组件id
     * 自定义对象名字首字母如果是小写左侧会有打√的叶子,首字母不是小写则没有
     *
     * 使用@Bean标注的组件,默认是单实例的
     * 外部无论对配置类中的这个组件的注册方法调用多少次(run.getBean)都是第一次注册进容器中的单实例对象
     * */
    @Bean("User01") //,,,
    public User User01(){
        return new User("zhangsan",18);
    }

    @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}
  • 自定义对象名字首字母如果是小写左侧会有打√的叶子,首字母不是小写则没有,并且会表明该组件在哪个配置类中

    SpringBoot注解_@Configuration与@Bean_第5张图片

    SpringBoot注解_@Configuration与@Bean_第6张图片

查看容器中的组件

@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) { 
         //获得IOC容器(最大的那个容器,根容器)
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);

		//从IOC容器中获取组件
        User user01 = run.getBean("User01", User.class);
        User user02 = run.getBean("User01", User.class);
        
        System.out.println("组件:"+(user01==user02));

        MyConfig myConfig01 = run.getBean(MyConfig.class);
        MyConfig myConfig02 = (MyConfig) run.getBean("myConfig");

        System.out.println(myConfig01);
        System.out.println(myConfig02);
        
       }
}
  • 被@SpringBootApplication自动扫描进IOC容器中的类组件名字默认首字母是小写的

    SpringBoot注解_@Configuration与@Bean_第7张图片

  • 使用@Bean标注的组件,默认是单实例的

    在这里插入图片描述

@Configuration注解中的proxyBeanMethod属性

proxyBeanMethod主要解决组件依赖的问题
  • 测试当 proxyBeanMethod=true时,获取到的组件实例是否为同一个

    /*
    * proxyBeanMethod:代理bean的方法 => 将真实组件实例隐藏起来了
    *       Full(proxyBeanMethod = true):配置类组件之间有依赖关系,方法会被调用得用到之前的单实例组件,用Full模式
    *       Lite(proxyBeanMethod = false):配置类组件之间无依赖关系yongLit模式加速容器启动过程,减少判断
    * proxyBeanMethods = true:
    *           1、代理配置类中的bean方法,获取组件实例;
    *              springboot总会检查该组件是否已经创建过,如果已经被实例化,则返回该实例,保持组件单实例
    * */
    @Configuration(proxyBeanMethods = true)
    public class MyConfig_proxyBeanMethod {
    
        @Bean
        public User user03(){
            return new User("lisi",19);
        }
    
        @Bean
        public Pet tomPet03(){
            return new Pet("tomDog");
        }
    }
    
    @SpringBootApplication
    public class MainApplication {
    
        public static void main(String[] args) {
            //获得IOC容器(最大的那个容器,根容器)
            ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
          
            MyConfig_proxyBeanMethod myConfig_proxy = run.getBean("myConfig_proxyBeanMethod", MyConfig_proxyBeanMethod.class);
            
            //从配置类中调用方法获取实例,不是用run.getBean获取实例
            User user03 = myConfig_proxy.user03();
            User user04 = myConfig_proxy.user03();
            System.out.println("user03 == user04:"+(user03==user04));
    
            Pet tomDog01 = myConfig_proxy.tomPet03();
            Pet tomDog02 = myConfig_proxy.tomPet03();
            System.out.println("tomDog01 == tomDog02:"+(tomDog01 == tomDog02));
        }
    }
    

    SpringBoot注解_@Configuration与@Bean_第8张图片

  • 测试当 proxyBeanMethod=false时

    @Configuration(proxyBeanMethods = false)
    

    SpringBoot注解_@Configuration与@Bean_第9张图片

类依赖测试:

@Configuration(proxyBeanMethods = true)
public class MyConfig_proxyBeanMethod {

    @Bean
    public User user03(){
        User lisi = new User("lisi", 19);
        //实际上tomPet03()应该是myConfig_proxy.tomPet03(0)
        lisi.setPet(tomPet03());
        return lisi;
    }

    @Bean
    public Pet tomPet03(){
        return new Pet("tomDog");
    }
}

@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {
        //获得IOC容器(最大的那个容器,根容器)
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        //proxyBeanMethod=true:检验用户的宠物和直接从IOC容器中获得是否是同一个
        User userPet = run.getBean("user03", User.class);
        Pet tomPet03 = run.getBean("tomPet03", Pet.class);
        System.out.println("userPet==tomPet03:"+(userPet.getPet()==tomPet03));
    }
}

1、 proxyBeanMethod=true

在这里插入图片描述

2、proxyBeanMethod=false

在这里插入图片描述

为什么proxyBeanMethod不直接对run起作用

当用run.getBean直接调用被proxyBeanMethod修饰的配置类中的Bean方法时(Bean方法没有被配置类调用过),proxyBeanMethod对run不起作用

@SpringBootApplication
public class MainApplication {
    public static void main(String[] args) { 
		//获得IOC容器(最大的那个容器,根容器)
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
 		User user03_run = run.getBean("user03", User.class);
        User user04_run = run.getBean("user03", User.class);
        System.out.println("user03_run == user04_run:"+(user03_run==user04_run));
		
		//获得配置类组件
		MyConfig_proxyBeanMethod myConfig_proxy = run.getBean("myConfig_proxyBeanMethod", MyConfig_proxyBeanMethod.class);
        
 		User user03_proy = myConfig_proxy.user03();
        User user04_proy = myConfig_proxy.user03();
        System.out.println("user03_proy == user04_proy:"+(user03_proy==user04_proy));
        
        Pet tomDog01 = myConfig_proxy.tomPet03();
        Pet tomDog02 = myConfig_proxy.tomPet03();
        System.out.println("tomDog01 == tomDog02:"+(tomDog01 == tomDog02));
    }
}
  • proxyBeanMethod=true

    SpringBoot注解_@Configuration与@Bean_第10张图片

  • proxyBeanMethod=false

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传SpringBoot注解_@Configuration与@Bean_第11张图片

你可能感兴趣的:(#,SpringBoot注解,spring,boot)