• Spring Boot之容器功能


    目录

    一.Spring 注入组件的注解

    二.@Configuration

    1.代码演示

    1.1JavaBean--》Monster.java

    1.2配置类

    1.3执行代码

    2.@Configuration 注意事项和细节

    三.@Import

    1.创建两个JavaBean类

    2.注入类

    3.测试注解的使用

    四.@Conditional

    1.@Conditional 介绍

    2.应用实例  

    五.@ImportResource

    1.作用:

    2.@ImportResource 应用实例 

    六.配置绑定

    1.代码演示

    2.配置绑定还有第 2 种方式

    海绵的思路(可能错误):

    3.注意事项和细节


    一.Spring 注入组件的注解

    @Component@Controller@Service@Repository

    说明: 这些在 Spring 中的传统注解仍然有效,通过这些注解可以给容器注入组件

    二.@Configuration

    SpringBoot, 通过 @Configuration 创建配置类来注入组件

    1.代码演示

    1.1JavaBean--》Monster.java

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

    1.2配置类

    1. /**
    2. * @author 海绵hong
    3. * @version 1.0
    4. *

    5. * 解读
    6. * 1. @Configuration 标识这是一个配置类, 等价于配置文件
    7. * 2. 程序员可以通过@Bean 注解注入bean对象到容器
    8. * 3. 当一个类被 @Configuration 标识,该类-Bean 也会注入容器
    9. */
    10. @Configuration
    11. public class BeanConfig {
    12. /**
    13. * 解读
    14. * 1. @Bean : 给容器添加组件, 就是Monster bean
    15. * 2. monster01() : 默认 你的方法名monster01 作为Bean的名字/id
    16. * 3. Monster : 注入类型, 注入bean的类型是Monster
    17. * 4. new Monster(200,"牛魔王",500,"疯魔拳") 注入到容器中具体的Bean信息
    18. * 5. @Bean(name = "monster_nmw") : 在配置、注入Bean指定名字/id monster_nmw
    19. * 6. 默认是单例注入
    20. * 7. 通过 @Scope("prototype") 可以每次返回新的对象,就多例.
    21. */
    22. //@Bean(name = "monster_nmw")
    23. @Bean
    24. //@Scope("prototype")
    25. public Monster monster01() {
    26. return new Monster(200, "牛魔王", 500, "疯魔拳");
    27. }
    28. }

    1.3执行代码

    1. //启动springboot应用程序/项目
    2. ConfigurableApplicationContext ioc =
    3. SpringApplication.run(MainApp.class, args);
    4. // ===演示 @Configuration start ====
    5. Monster monster01 = ioc.getBean("monster01", Monster.class);
    6. Monster monster02 = ioc.getBean("monster01", Monster.class);
    7. System.out.println("monster01--" + monster01 + " " + monster01.hashCode());
    8. System.out.println("monster02--" + monster02 + " " + monster02.hashCode());
    9. //===演示 @Configuration end ====

    2.@Configuration 注意事项和细节

    1. 配置类本身也是组件, 因此也可以获取 , 测试 修改 MainApp.java
    1. public static void main(String[] args) {
    2. ConfigurableApplicationContext ioc =
    3. SpringApplication.run(MainApp.class, args);
    4. //解读
    5. //1. ioc.getBean("monster01", Monster.class) 是从 BeanConfig 配置类/容器获取 bean 实例
    6. //2. 默认是单列模式, 所以 monster01 == monster02
    7. //获取 BeanConfig 配置类的组件/bean 实例
    8. Monster monster01 = ioc.getBean("monster01", Monster.class);
    9. System.out.println(monster01);
    10. Monster monster02 = ioc.getBean("monster01", Monster.class);
    11. System.out.println(monster01 == monster02);
    12. //解读
    13. //配置类本身也是组件, 因此也可以获取
    14. BeanConfig beanConfig = ioc.getBean(BeanConfig.class);
    15. System.out.println("beanConfig= " + beanConfig);
    16. }
    2. SpringBoot2 新增特性: proxyBeanMethods 指定 Full 模式 (全模式)和 Lite 模式(简化模式)
    1. proxyBeanMethods:代理bean的方法
     (1) Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的, 是代理方式】
     (2) Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的, 是非代理方式】 
    (3) 特别说明: proxyBeanMethods 是在 调用@Bean方法 才生效,因此,需要先获取BeanConfig 组件,再调用方法 而不是直接通过 SpringBoot 主程序得到的容器来获取bean, 注意观察直接通过ioc.getBean() 获取Bean, proxyBeanMethods 值并没有生效 
    (4) 如何选择: 组件依赖必须使用Full模式默认。如果不需要组件依赖使用 Lite模 
    (5) Lite模 也称为轻量级模式,因为不检测依赖关系,运行速度快
    
    1. @Configuration(proxyBeanMethods = false)
    2. public class BeanConfig {
    1. //===演示@Configuration(proxyBeanMethods = xxx) start
    2. //1. 先得到BeanConfig组件
    3. BeanConfig beanConfig = ioc.getBean(BeanConfig.class);
    4. Monster monster_01 = beanConfig.monster01();
    5. Monster monster_02 = beanConfig.monster01();
    6. System.out.println("monster_01-" + monster_01 + " " + monster_01.hashCode());
    7. System.out.println("monster_02-" + monster_02 + " " + monster_02.hashCode());
    8. //特别说明: proxyBeanMethods 是在 调用@Bean方法 才生效,因此,需要先获取BeanConfig 组件,再调用方法
    9. //1. 而不是直接通过 SpringBoot 主程序得到的容器来获取bean, 注意观察直接通过ioc.getBean() 获取Bean, proxyBeanMethods 值并没有生效
    10. Monster monster01 = ioc.getBean("monster01", Monster.class);
    11. Monster monster02 = ioc.getBean("monster01", Monster.class);
    12. System.out.println("monster01-" + monster01 + " " + monster01.hashCode());
    13. System.out.println("monster02-" + monster02 + " " + monster02.hashCode());
    14. //===演示@Configuration(proxyBeanMethods = xxx) end
    3. 配置类可以有多个 , 就和 Spring 可以有多个 ioc 配置文件是一个道理

    三.@Import

    SpringBoot, 通过 @Import 来注入组件(和@Configuration一样都是注入bean

    1.创建两个JavaBean类

    Cat+Dog

    2.注入类

    1. /**
    2. * 解读
    3. * 1. @Import 代码 可以看到,可以指定 class的数组, 可以注入指定类型的Bean
    4. * public @interface Import {
    5. *
    6. * Class[] value()}
    7. *
    8. * 2. 通过@Import 方式注入了组件, 默认组件名字/id就是对应类型的全类名
    9. */
    10. @Import({Dog.class, Cat.class})

    3.测试注解的使用

    1. //启动springboot应用程序/项目
    2. ConfigurableApplicationContext ioc =
    3. SpringApplication.run(MainApp.class, args);
    4. //===测试@Import 使用 start
    5. Dog dogBean = ioc.getBean(Dog.class);
    6. Cat catBean = ioc.getBean(Cat.class);
    7. System.out.println("dogBean--" + dogBean);
    8. System.out.println("catBean--" + catBean);
    9. //===测试@Import 使用 end

    四.@Conditional

    1.@Conditional 介绍

    1. 条件装配:满足 Conditional 指定的条件,则进行组件注入
    2. @Conditional 是一个根注解,下面有很多扩展注解

    2.应用实例  

    1. 要求 : 演示在 SpringBoot, 如何通过 @ConditionalOnBean 来注入组件
    2. 只有在容器中有 name = monster_nmw 组件时,才注入 dog01, 代码如图
    1. @Bean
    2. /**
    3. * 解读
    4. * 1. @ConditionalOnBean(name = "monster_nmw") 表示
    5. * 2. 当容器中有一个Bean , 名字是monster_nmw (类型不做约束), 就注入dog01这个Dog bean
    6. * 3. 如果没有 名字是monster_nmw Bean 就不注入dog01这个Dog bean
    7. * 4. 还有很多其它的条件约束注解,小伙伴可以自己测试
    8. *
    9. * 5. @ConditionalOnMissingBean(name = "monster_nmw") 表示在容器中,
    10. * 没有 名字/id 为 monster_nmw 才注入dog01这个Bean
    11. *
    12. * 6. @ConditionalOnBean(name = "monster_nmw") 也可以放在配置类
    13. * 表示对该配置类的所有要注入的组件,都进行条件约束.
    14. *
    15. */
    16. @ConditionalOnBean(name = "monster_nmw")
    17. //@ConditionalOnMissingBean(name = "monster_nmw")
    18. public Dog dog01() {
    19. return new Dog();
    20. }

    五.@ImportResource

    1.作用:

    原生配置文件引入 , 也就是可以直接导入 Spring 传统的 beans.xml ,可以认 为是 SpringBoot Spring 容器文件的兼容 .(原来依靠借口或者类来导入,现在可以使用该注解进行判断)

    2.@ImportResource 应用实例 

    1. @Configuration
    2. //导入beans.xml - 就可以获取到beans.xml 中配置bean
    3. @ImportResource(locations = {"classpath:beans.xml","classpath:beans02.xml"})//配置两个bean文件
    4. public class BeanConfig3 {
    5. }
    1. //===测试@Import 使用 start
    2. Dog dogBean = ioc.getBean(Dog.class);
    3. Cat catBean = ioc.getBean(Cat.class);
    4. System.out.println("dogBean--" + dogBean);
    5. System.out.println("catBean--" + catBean);
    6. //===测试@Import 使用 end

    六.配置绑定

    一句话:使用 Java 读取到 SpringBoot 核心配置文件 application.properties 的内容,
    并且把它封装到 JavaBean

    1.代码演示

    1. #设置Furn的属性k-v
    2. #前面的 furn01 是用于指定/区别不同的绑定对象, 这样可以再绑定Furn bean属性值时
    3. #通过furn01 前缀进行区分
    4. #furn01.id 中的id 就是你要绑定的 Furn bean的属性名
    5. furn01.id=100
    6. furn01.name=TV
    7. furn01.price=1000.9
    1. @Component
    2. @ConfigurationProperties(prefix = "furn01")
    3. public class Furn {
    4. private Integer id;
    5. private String name;
    6. private Double price;
    7. }

    会读取核心配置文件的信息,然后放入容器

    2.配置绑定还有第 2 种方式

    注意 : 注销
    @Component 需 要 在 BeanConfig.java( 说 明 : 也 可 以 是 其 它 配 置 类 ) 配 置
    @EnableConfigurationProperties ( Furn . class ), 否则会提示错误

     

    1. //@EnableConfigurationProperties(Furn.class)解读
    2. //1、开启 Furn 配置绑定功能
    3. //2、把 Furn 组件自动注册到容器中
    4. @EnableConfigurationProperties(Furn.class)
    5. public class BeanConfig {
    6. }

    海绵的思路(可能错误):

    @Component注解标识掉之后,就不会去读取到容器中,但是在控制器中@EnableConfigurationProperties(Furn.class)被添加,那么底层应该就是这样一个思路:将这个启用配置属性明确配置那个类的信息,然后在那个对应的JavaBean类中有@ConfigurationProperties(prefix = "furn01")这个配置就可以读取到,并且直接将这个信息发送到了控制器中,所有在之后添加了那个注解之后便没有报错

    3.注意事项和细节

    1. 如果 application.properties 有中文 , 需要转成 unicode 编码写入 , 否则出现乱码
    1. #设置属性 k-v
    2. furn01.id=100
    3. furn01.name=soft_chair\u6c99\u53d1!!
    4. furn01.price=45678.9
    2. 使用 @ConfigurationProperties (prefix = "furn01" ) 会提示如下信息 , 但是不会影响使用

    3. 解决 @ConfigurationProperties(prefix = "furn01") 提示信息, pom.xml 增加依赖, 即可 

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-configuration-processorartifactId>
    4. <optional>trueoptional>
    5. dependency>
  • 相关阅读:
    QT不同子类间共享变量,教你简单、规范的方法
    【公益案例展】 网易“双碳”智控系统——开源开放赋能绿色发展
    LeetCode·71.简化路径·栈模拟
    “蔚来杯“2022牛客暑期多校训练营2
    四元数的可视化
    洛谷——P1164 小A点菜
    opencv的色彩空间
    MySQL目录结构
    跨平台编程开发工具Xojo 2023 Release mac中文版功能介绍
    史上最全的Selenium三大等待介绍
  • 原文地址:https://blog.csdn.net/weixin_54107527/article/details/127870247