SpringBoot:(四)底层注解详解

时间:2022-11-07 10:02:44

笔记来源:【尚硅谷】SpringBoot2零基础入门教程(spring boot2干货满满)

4.1 @Configuration详解

  • 基本使用:声明当前类是SpringBoot的一个配置类

  • Full模式Lite模式

    • Full(proxyBeanMethods = true):保证每个@Bean方法被调用多少次返回的组件都是单实例的(默认)
    • Lite(proxyBeanMethods = false):每个@Bean方法被调用多少次返回的组件都是新创建的
  • 示例:

    @Configuration(proxyBeanMethods = false)
    public class MyConfig {
        @Bean("tom")
        public Pet tomcatPet(){
            return new Pet("tomcat");
        }
    
        @Bean
        public User user01(){
            User user = new User("张三", 18);
            user.setPet(tomcatPet());
            return user;
        }
    }
    
  • 进阶测试1:配置类MyConfig的注解@Configuration(proxyBeanMethods = false)

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        String[] beanDefinitionNames = run.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
            System.out.println(beanDefinitionName);
        }
        // 从容器总获取同名组件是否相同
        Pet tom1 = run.getBean("tom", Pet.class);
        Pet tom2 = run.getBean("tom", Pet.class);
        System.out.println("同名组件tom1与tom2是否相同:" + (tom1 == tom2));
    
        // 从组件中获取配置类实例
        MyConfig myConfig = run.getBean(MyConfig.class);
        System.out.println("配置类实例:" + myConfig);
    
        // 直接使用配置类的方法获取对象
        User user = myConfig.user01();
        User user1 = myConfig.user01();
        System.out.println("直接调用方法获取的对象是否相同:" +(user == user1));
    
        // 获取嵌套对象
        User user01 = run.getBean("user01", User.class);
        Pet tom = run.getBean("tom", Pet.class);
    
        System.out.println("嵌套的对象是否和容器对象相同:"+(user01.getPet() == tom));
    }
    

    SpringBoot:(四)底层注解详解

    SpringBoot:(四)底层注解详解

  • 进阶测试2:配置类MyConfig的注解@Configuration(proxyBeanMethods = true)
    SpringBoot:(四)底层注解详解

总结

  • 配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断
  • 配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式(默认)

4.2 @Component、@Controller、@Service、@Repository、@Bean

@Component:通用的注解,可标注任意类为Spring的组件。如果一个Bean不知道属于哪个层,可以使用@Component注解标注。

@Repository:标注一个类为持久化层组件。与@Component、@Controller、@Service在功能上是一致的。

@Service:标注一个类为服务层组件。与@Component、@Controller、@Repository在功能上是一致的。

@Controller:标注一个类为控制层组件。与@Component、@Service、@Repository在功能上是一致的。

@Bean:必须和配置类注解@Configuration一起工作,标注在方法上,返回某个实例的方法,这个实例就会交给Spring容器管理。

4.3 @Import导入组件

  • 基本使用:@Import({User.class, DBHelper.class})给容器中自动创建出这两个类型的组件默认组件的名字就是全类名

    @Import({User.class, DBHelper.class})
    @Configuration(proxyBeanMethods = false)
    public class MyConfig {
    }
    
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        String[] users = run.getBeanNamesForType(User.class);
        for (String user : users) {
            System.out.println(user);
        }
        String[] dbHelpers = run.getBeanNamesForType(DBHelper.class);
        for (String dbHelper : dbHelpers) {
            System.out.println(dbHelper);
        }
    }
    

    SpringBoot:(四)底层注解详解

4.4 @Conditional条件装配

  • 基本使用:条件装配,满足Conditional指定的条件,则进行组件注入。可以配置在方法上,也可以配置在类上。

  • 类别:

    SpringBoot:(四)底层注解详解

  • 示例

    @Import({User.class, DBHelper.class})
    @Configuration(proxyBeanMethods = true)
    public class MyConfig {
    
        @Bean("tom1")
        public Pet tomcatPet(){
            return new Pet("tomcat");
        }
        
        // 当容器中有某个对象的时候才进行注入
        // 容器中有tom1,没有tom,看user01对象是否能注册到容器中
        @ConditionalOnBean(name = "tom")
        @Bean
        public User user01(){
            User user = new User("张三", 18);
            user.setPet(tomcatPet());
            return user;
        }
    }
    
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
        User user01 = run.getBean("user01", User.class);
        System.out.println(user01);
    }
    

    SpringBoot:(四)底层注解详解

4.5 @ImportResource导入Spring配置文件

  • 基本使用:导入外部的bean.xml配置文件

  • 示例

    <?xml version="1.0" encoding="UTF-8"?>
    <beans ...">
        <bean id="haha" class="com.lun.boot.bean.User">
            <property name="name" value="zhangsan"></property>
            <property name="age" value="18"></property>
        </bean>
        <bean id="hehe" class="com.lun.boot.bean.Pet">
            <property name="name" value="tomcat"></property>
        </bean>
    </beans>
    
    @ImportResource("classpath:beans.xml")
    public class MyConfig {
    ...
    }
    
    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
    
    	boolean haha = run.containsBean("haha");
    	boolean hehe = run.containsBean("hehe");
    	System.out.println("haha:"+haha);
    	System.out.println("hehe:"+hehe);
    }
    

    SpringBoot:(四)底层注解详解

4.6 @ConfigurationProperties配置绑定

  • 基本使用:读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用

  • 传统方法:

    public class getProperties {
        public static void main(String[] args) throws FileNotFoundException, IOException {
            Properties pps = new Properties();
            pps.load(new FileInputStream("a.properties"));
            Enumeration enum1 = pps.propertyNames();//得到配置文件的名字
            while(enum1.hasMoreElements()) {
                String strKey = (String) enum1.nextElement();
                String strValue = pps.getProperty(strKey);
                System.out.println(strKey + "=" + strValue);
                //封装到JavaBean。
            }
        }
    }
    
  • Spring Boot一种配置配置绑定:@ConfigurationProperties + @Component

    • 假设有配置文件application.properties

      mycar.brand=BYD
      mycar.price=100000
      
    • 只有在容器中的组件,才会拥有SpringBoot提供的强大功能

      ...
      @Component
      @ConfigurationProperties(prefix = "mycar")
      public class Car {
      	private String brand;
          private int price;
      }
      
    • 示例:

      public static void main(String[] args) {
              ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
              Car haha = run.getBean("car", Car.class);
              System.out.println(haha);
          }
      

      SpringBoot:(四)底层注解详解

  • Spring Boot另一种配置配置绑定:@EnableConfigurationProperties + @ConfigurationProperties

    • 开启Car配置绑定功能

      @EnableConfigurationProperties(Car.class) // 注入对象的名称为全类名,不再是类名首字母小写了
      public class MyConfig {
      ...
      }
      
    • 把这个Car这个组件自动注册到容器中

      @ConfigurationProperties(prefix = "mycar")
      public class Car {
      	private String brand;
          private int price;
      }
      
    • 示例

      public static void main(String[] args) {
          ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
          String[] beanNamesForType = run.getBeanNamesForType(Car.class);
          for (String s : beanNamesForType) {
              System.out.println(s);
          }
          Car car = run.getBean(Car.class);
          System.out.println(car);
      }
      

      SpringBoot:(四)底层注解详解