springboot注解之@Import @Conditional @ImportResource @ConfigurationProperties @EnableConfigurationProperties

1.包结构

 

 

2.主程序类

 1 @SpringBootApplication(scanBasePackages={"com.atguigu"})
 2 public class MainApplication {
 3     public static void main(String[] args) {
 4         //1.返回IOC容器
 5         ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
 6         //2.获取容器内所有组件的名称
 7         String[] names = run.getBeanDefinitionNames();
 8         for (String name : names) {
 9             System.out.println(name);
10         }
11 
12 
13         //获取指定组件类型的所有组件名称
14         String[] beanNamesForType = run.getBeanNamesForType(User.class);
15         //com.atguigu.boot.bean.User   --->通过@Import({User.class})在容器中自动创建的组件,默认组件名是全类名
16         //user01   --->配置类中通过@Bean给容器注册组件,组件名默认是方法名
17         //haha     --->从spring配置文件beans.xml导入添加到容器中的haha组件
18         for (String bean : beanNamesForType) {
19             System.out.println(bean);
20         }
21 
22         boolean tomcatPet = run.containsBean("tomcatPet");
23         System.out.println("容器中是否有tomcatPet组件? " + tomcatPet);
24 
25         boolean user01 = run.containsBean("user01");
26         System.out.println("容器中是否有user01组件? " + user01);
27 
28         //spring配置文件beans.xml只有导入到了容器中,
29         //这个配置文件中配置的bean才能添加到容器中
30         //导入方式:一般在配置类上加上@ImportResource("classpath:beans.xml"),
31         // 括号内指定xml的文件路径
32         boolean haha = run.containsBean("haha");
33         boolean hehe = run.containsBean("hehe");
34         System.out.println(haha);
35         System.out.println(hehe);
36 
37         Car car = run.getBean(Car.class);
38         System.out.println(car);
39 
40     }
41 }

 

3.资源文件

 application.properties

1 #每一个key都是某个类的属性,而且都有默认值,可以修改
2 server.port=8888
3 
4 #默认文件上传的最大文件大小是1MB,修改为10MB
5 #spring.servlet.multipart.max-file-size=10MB
6 
7 mycar.brand=BYD
8 mycar.price=100000

 

 beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


<!--    spring使用<bean>标签给容器添加组件-->
    <bean id="haha" class="com.atguigu.boot.bean.User">
        <property name="name" value="张三"/>
        <property name="age" value="18"/>
    </bean>

    <bean id="hehe" class="com.atguigu.boot.bean.Pet">
        <property name="name" value="helloKitty"/>
    </bean>

</beans>

 

4.config包下配置类

 1 package com.atguigu.boot.config;
 2 
 3 import com.atguigu.boot.bean.Car;
 4 import com.atguigu.boot.bean.Pet;
 5 import com.atguigu.boot.bean.User;
 6 import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 7 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 8 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 9 import org.springframework.context.annotation.*;
10 
11 /**
12     1.配置类里面使用@Bean标注在方法上给容器注册组件,默认是单实例的
13     2.配置类本身也是组件
14     3.proxyBeanMethods:配置类是否作为代理bean来调用方法
15         如果 proxyBeanMethods = true 则是Full模式(重量级模式)
16             ---> 此模式下,配置类作为代理bean来调用方法,springboot都会去容器里面检查有没有这个组件,如果有,就使用容器中的组件,确保单实例,形成组件依赖
17         如果 proxyBeanMethods = false 则是Lite模式(轻量级模式)
18             ---> 此模式下,配置类是作为普通类调用方法,springboot不会去容器里面检查组件,不会形成组件依赖,项目启动运行快
19 
20     4.最佳实战
21         配置类组件之间无依赖关系,用Lite模式加速容器启动过程,减少判断
22         配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式
23 
24     5.@Import({User.class})
25         给容器中自动创建出这个类型的组件,默认组件名是其全类名
26 
27     6.@Conditional 条件装配:满足Conditional指定的条件,组件才会被添加到容器中
28     @ConditionalOnBean(name="user01")
29     @ConditionalOnMissingBean(name = "user01")
30 
31     7.@ImportResource("classpath:beans.xml")   将spring配置文件导入到容器中
32 
33     8.配置绑定(属性)的两种方式
34         第一种方式:目标bean上加上如下两个注解
35             @Component  //将目标bean作为组件添加到容器中
36             @ConfigurationProperties("mycar")  //配置属性:将配置文件中指定前缀的属性值映射到对象的属性
37             注意:由于只有在容器中的组件,才能拥有SpringBoot提供的强大功能,所以这两个注解一般配合使用
38         第二种方式
39             在目标bean上加上@ConfigurationProperties("mycar")
40             在配置类上加上@ConfigurationProperties(Car.class) //1.开启Car的属性绑定功能 2.将Car组件自动注册到容器中
41             注:这种方法比较适合用于目标bean是第三方jar包里的类,因为没法使用第一种方法在它上面标注@Component
42 
43  */
44 
45 @Import({User.class})
46 @Configuration(proxyBeanMethods = false)  //告诉Springbooot这是一个配置类
47 //@ConditionalOnBean(name="user01")  //条件装配:当满足容器中有user01组件这个条件,该配置类中带有@Bean的组件方法才能添加组件到容器中
48 //@ConditionalOnMissingBean(name = "user01") //条件装配:当容器中没有user01组件时,该配置类中带有@Bean的组件方法才能添加组件到容器中
49 @ImportResource("classpath:beans.xml")
50 @EnableConfigurationProperties(Car.class)
51 public class Myconfig {
52 
53     /**
54      * 外部无论对配置类中的组件注册方法调用多少次,获取的都是之前注册在容器中的单实例对象
55      * @return
56      */
57     //执行此语句会判断容器中是否有tomcatPet组件,由于程序代码顺序执行,所以容器里面此时没有tomcatPet组件
58     //因此user01组件的条件不满足,容器不会添加user01组件
59 //    @ConditionalOnBean(name="tomcatPet")  //条件装配:只有当容器中有tomcatPet组件时,user01组件才能添加到容器中
60     @Bean   //给容器中添加组件,默认以方法名作为组件id(组件名)。返回类型就是组件类型,返回值就是组件在容器中的实例
61     public User user01() {
62         User user = new User("zhangsan", 20);
63         //如果@Configuration(proxyBeanMethods = true),
64         // 此时容器中的user01组件依赖容器中的tomcatPet组件
65         user.setPet(cat());
66         return user;
67     }
68 
69 
70     @Bean("tomcatPet") //此时组件名就是tomcatPet,而不是方法名了
71     public Pet cat() {
72         return new Pet("HelloKitty");
73     }
74 }

 

5.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 }

 

 Car

 1 /**
 2  * 只有在容器中的组件,才能拥有SpringBoot提供的强大功能,
 3  * 所以在使用@ConfigurationProperties("mycar")配置属性的前提是此bean为组件
 4  */
 5 
 6 //@Component  //将此bean作为组件添加到容器中
 7 @ConfigurationProperties("mycar")
 8 //配置属性:将配置文件application.properties中指定前缀mycar的属性值映射到对象中相应的属性
 9 public class Car {
10     private String brand;//品牌
11     private Double price;//价格
12 
13     public Car() {
14     }
15 
16     public Car(String brand, Double price) {
17         this.brand = brand;
18         this.price = price;
19     }
20 
21     public String getBrand() {
22         return brand;
23     }
24 
25     public void setBrand(String brand) {
26         this.brand = brand;
27     }
28 
29     public Double getPrice() {
30         return price;
31     }
32 
33     public void setPrice(Double price) {
34         this.price = price;
35     }
36 
37     @Override
38     public String toString() {
39         return "Car{" +
40                 "brand='" + brand + '\'' +
41                 ", price=" + price +
42                 '}';
43     }
44 }

 

6.controller包下控制类

 1 /**
 2  *
 3  * 默认包
 4  * springboot会将主程序所在包及其所有子包下的组件扫描进IOC容器
 5  *
 6  * 如果组件不在主程序所在包或者其子包下,比如WorldController组件,则必须将此组件所在全包名com.atguigu,
 7  * 声明在主程序类的@SpringBootApplication注解后面,
 8  * @SpringBootApplication(scanBasePackages={"com.atguigu"}),如果多个以字符串数组的形式
 9  * 这样此组件才能被扫描进IOC容器
10  */
11 
12 
13 //@ResponseBody 方法直接返回字符串给浏览器
14 //@Controller
15 //  @RestController  =  @ResponseBody + @Controller
16 @RestController
17 public class HelloController {
18     @Autowired  //自动注入组件
19     Car car;
20 
21     @RequestMapping("/car")
22     public Car car() {
23         return car;
24     }
25 
26     @RequestMapping("/hello")
27     public String handle01() {
28         return "hello,Spring boot 2!" + " 你好";
29     }
30 }

 

posted @ 2021-03-11 19:34  dog_IT  阅读(164)  评论(0编辑  收藏  举报