springboot注解之@Configuration 和 @Bean


1.包結構

 

 

 

2.主程序類 

 1 /**
 2  * 主程序類
 3  * @SpringBootApplication:這是一個springboot應用
 4  *
 5  * @SpringBootApplication
 6  *
 7  * 等同於下面的三個包
 8  * @SpringBootConfiguration
 9  * @EnableAutoConfiguration
10  * @ComponentScan(com.atguigu.boot)  ---->默認組件掃描基礎包是主程序類MainApplication所在包及其子包
11  *
12  *
13  */
14 @SpringBootApplication(scanBasePackages={"com.atguigu"})
15 public class MainApplication {
16     public static void main(String[] args) {
17         //1.返回IOC容器
18         ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
19         //2.獲取容器內所有組件的名稱
20         String[] names = run.getBeanDefinitionNames();
21         for (String name : names) {
22             System.out.println(name);
23         }
24 
25         //3.從容器中獲取指定組件
26         User user01 = run.getBean("user01", User.class);
27         User user02 = run.getBean("user01", User.class);
28         System.out.println("使用同一個組件id,多次獲取組件,是否是同一個組件實例:" + (user01 == user02));
29 
30         //配置類本身也是組件
31         Myconfig myConfig = run.getBean(Myconfig.class);
32         Myconfig myConfig2 = run.getBean(Myconfig.class);
33         System.out.println(myConfig == myConfig2);
34 
35         //4. 配置類默認情況下是@Configuration(proxyBeanMethods = true),代表配置類此時不是一個普通的類
36         //可以把它理解為代理bean,此時打印結果是 com.atguigu.boot.config.Myconfig$$EnhancerBySpringCGLIB$$a3f7b687@5b5caf08
37         //如果配置類上@Configuration(proxyBeanMethods = false),此時配置類就是一個普通類
38         //此時打印結果:com.atguigu.boot.config.Myconfig@6e28bb87
39         System.out.println(myConfig);
40 
41         //5.如果@Configuration(proxyBeanMethods = true) 開啟代理bean調用方法
42         //則當配置類對象調用其注冊組件方法去獲取相應組件時,Springboot總會檢查組件是否在容器中
43         //保持組件單實例
44         User user1 = myConfig.user01();
45         User user2 = myConfig.user01();
46         //默認情況下@Configuration(proxyBeanMethods = true),打印結果是 true
47         //如果@Configuration(proxyBeanMethods = false),則打印結果是 false
48         System.out.println("配置類是作為代理bean從容器中獲取單例組件呢?還是作為普通類調用方法呢? " + (user1 == user2));
49 
50         User user3 = run.getBean("user01", User.class);
51         Pet tomcatPet = run.getBean("tomcatPet", Pet.class);
52         //如果@Configuration(proxyBeanMethods = true),
53         //此時容器中的user01組件依賴容器中的tomcatPet組件,返回 true
54         System.out.println("用戶的寵物是否是容器中的那個單實例寵物組件? " + (user3.getPet() == tomcatPet));
55 
56     }
57 }

 

3.bean包下的兩個實體類

User

 1 public class User {
 2     private String name;
 3     private Integer age;
 4 
 5     private Pet pet;
 6 
 7     public User() {
 8     }
 9 
10     public User(String name, Integer age) {
11         this.name = name;
12         this.age = age;
13     }
14 
15     public Pet getPet() {
16         return pet;
17     }
18 
19     public void setPet(Pet pet) {
20         this.pet = pet;
21     }
22 
23     public String getName() {
24         return name;
25     }
26 
27     public void setName(String name) {
28         this.name = name;
29     }
30 
31     public Integer getAge() {
32         return age;
33     }
34 
35     public void setAge(Integer age) {
36         this.age = age;
37     }
38 
39     @Override
40     public String toString() {
41         return "User{" +
42                 "name='" + name + '\'' +
43                 ", age=" + age +
44                 ", pet=" + pet +
45                 '}';
46     }
47 }

  Pet

 1 public class Pet {
 2     private String name;
 3 
 4     public Pet() {
 5     }
 6 
 7     public Pet(String name) {
 8         this.name = name;
 9     }
10 
11     public String getName() {
12         return name;
13     }
14 
15     public void setName(String name) {
16         this.name = name;
17     }
18 
19     @Override
20     public String toString() {
21         return "Pet{" +
22                 "name='" + name + '\'' +
23                 '}';
24     }
25 }

 

4.config包下的配置類 Myconfig

 1 /**
 2     1.配置類里面使用@Bean標注在方法上給容器注冊組件,默認是單實例的
 3     2.配置類本身也是組件
 4     3.proxyBeanMethods:配置類是否作為代理bean來調用方法
 5         如果 proxyBeanMethods = true 則是Full模式(重量級模式)
 6             ---> 此模式下,配置類作為代理bean來調用方法,springboot都會去容器里面檢查有沒有這個組件,如果有,就使用容器中的組件,確保單實例,形成組件依賴
 7         如果 proxyBeanMethods = false 則是Lite模式(輕量級模式)
 8             ---> 此模式下,配置類是作為普通類調用方法,springboot不會去容器里面檢查組件,不會形成組件依賴,項目啟動運行快
 9 
10     4.最佳實戰
11         配置類組件之間無依賴關系,用Lite模式加速容器啟動過程,減少判斷
12         配置類組件之間有依賴關系,方法會被調用得到之前單實例組件,用Full模式
13  */
14 @Configuration(proxyBeanMethods = false)  //告訴Springbooot這是一個配置類
15 public class Myconfig {
16 
17     /**
18      * 外部無論對配置類中的組件注冊方法調用多少次,獲取的都是之前注冊在容器中的單實例對象
19      * @return
20      */
21 
22     @Bean   //給容器中添加組件,默認以方法名作為組件id(組件名)。返回類型就是組件類型,返回值就是組件在容器中的實例
23     public User user01() {
24         User user = new User("zhangsan", 20);
25         //如果@Configuration(proxyBeanMethods = true),
26         // 此時容器中的user01組件依賴容器中的tomcatPet組件
27         user.setPet(cat());
28         return user;
29     }
30 
31 
32     @Bean("tomcatPet") //此時組件名就是tomcatPet,而不是方法名了
33     public Pet cat() {
34         return new Pet("HelloKitty");
35     }
36 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM