@Import
应用实例
说明: 演示在SpringBoot, 如何通过@Import 来注入组件
创建quickstart\src\main\java\com\nlc\springboot\bean\Cat.java
public class Cat { }
创建quickstart\src\main\java\com\nlc\springboot\bean\Dog.java
public class Dog { }
- 修改BeanConfig.java 通过@Import 注入组件
/** * Import 可以传入一个数组,可以一次注入多个组件 * public @interface Import { * Class<?>[] value(); * } * 注意@Import 方式注入的组件, 默认组件的名字就是全类名 */ @Import({Dog.class, Cat.class}) // @Configuration//标识这是一个配置类: 等价配置文件 @Configuration(proxyBeanMethods = false) public class BeanConfig { }
- 修改MainApp.java 完成测试
public static void main(String[] args) { //启动springboot应用程序/项目 ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args); Dog dogBean = ioc.getBean(Dog.class); Cat catBean = ioc.getBean(Cat.class); System.out.println("dogBean--" + dogBean); System.out.println("catBean--" + catBean); }
默认类型导入是单例的,如果有多个同类型bean就会报错。
@Conditional
@Conditional 介绍
- 条件装配:满足Conditional 指定的条件,则进行组件注入
- @Conditional 是一个根注解,下面有很多扩展注解
应用实例
- 要求: 演示在SpringBoot, 如何通过@ConditionalOnBean 来注入组件
- 只有在容器中有name = monster_nmw 组件时,才注入dog01, 代码如图
@Bean public Dog dog01() { return new Dog(); }
- 先测试下,当前是否能注入dog01
System.out.println("容器是否注入了dog01= " + ioc.containsBean(“dog01”));
4.修改BeanConfig.java , 加入@ConditionalOnBean 条件约束,并完成测试
@Import({Dog.class, Cat.class}) // @Configuration//标识这是一个配置类: 等价配置文件 @Configuration(proxyBeanMethods = false) //设置每次获取bean都创建新的,要符合条件才生效 public class BeanConfig { /** * 1. @Bean : 给容器中添加组件 * 2. monster01() : 默认方法名作为组件的id * 3. Monster: 返回类型就是组件类型, 返回的值就是new Monster(100, "牛魔王", 500, " 芭蕉扇") * 4. @Bean("monster_nmw"): 重新指定组件的id = “monster_nmw” * 5. 配置类里面使用@Bean 标注在方法上给容器注册组件,默认是单实例的 */ // @Bean("monster_nmw") @Bean public Monster monster01() { return new Monster(100, "牛魔王", 500, "芭蕉扇"); } /** * @ConditionalOnBean(name = "monster_nmw"): * 1. 表示只有容器中注入了name = monster_nmw 的组件,下面的组件(dog01)才会被注入 * 2. @ConditionalOnBean(name = "monster_nmw") 也可以放在类名处, * 则表示对该配置类中所有要注入的组件都进行条件约束 * 3. 还有很多其它条件约束注解,用到时在讲解. */ @ConditionalOnBean(name = "monster_nmw") @Bean public Dog dog01() { return new Dog(); } }
自己测试,打开注解,看是否注入。
@ImportResource
作用:原生配置文件引入, 也就是可以直接导入Spring 传统的beans.xml ,可以认为是SpringBoot 对Spring 容器文件的兼容.
@ImportResource 应用实例
- 需求: 将beans.xml 导入到BeanConfig.java 配置类, 并测试是否可以获得beans.xml注入/配置的组件
将beans.xml放在resource资源目录下
<?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"> <!--配置了Monster bean--> <bean id="monster03" class="com.nlc.springboot.bean.Monster"> <property name="name" value="牛魔王~"></property> <property name="age" value="5000"></property> <property name="skill" value="芭蕉扇~"></property> <property name="id" value="1000"></property> </bean> </beans>
- 修改BeanConfig.java / 或者创建新的BeanConfig3.java(建议创建新的配置类) 来测试,使用@ImportResource 导入beans.xml
//外部导入bean @Import({Dog.class, Cat.class}) // @Configuration//标识这是一个配置类: 等价配置文件 @Configuration(proxyBeanMethods = false) //导入beans.xml @ImportResource("classpath:beans.xml") public class BeanConfig { }
- 在MainApp.java 测试
public static void main(String[] args) { ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args); System.out.println("容器是否注入了dog01= " + ioc.containsBean("dog01")); System.out.println("monster03: " + ioc.containsBean("monster03")); System.out.println(ioc.getBean("monster03")); }
配置绑定
说明:使用Java 读取到SpringBoot 核心配置文件application.properties 的内容,并且把它封装到JavaBean 中
应用实例
- 需求: 将application.properties 指定的k-v 和JavaBean 绑定
#默认server.port=8080 server.port=10000 #比如: 默认spring.servlet.multipart.max-file-size=1MB #默认配置最终都是映射到某个类上,比如这里配置会映射到MultipartProperties spring.servlet.multipart.max-file-size=10MB #设置属性k-v #前面的futn01用于指定/区分不同的绑定对象 furn01.id=100 furn01.name=soft_chair!! furn01.price=45678.9
- 创建quickstart\src\main\java\com\nlc\springboot\bean\Furn.java
@Component @ConfigurationProperties(prefix = "furn01") //指定前缀。以 前缀匹配properties 文件的值,将值注入bean /** * 说明: * 1. Equivalent to {@code @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode} * 2. @Data 注解等价使用了 如下注解 @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode */ //@Data //说明: @NoArgsConstructor 在编译时,会生成无参构造器, 前面说过,默认情况下,会生成一个无参构造器 //说明:当我们有其它构造器生成时,如果你希望仍然有无参构造器就需要使用@NoArgsConstructor指定一下,否则就会覆盖无参构造器,从而代码错误 @NoArgsConstructor //说明:@AllArgsConstructor 在编译时,会生成全参构造器 @AllArgsConstructor //@ToString 在编译时,生成toString, 默认情况下,会生成一个无参构造器 @ToString //生成所有的set/get方法 @Setter @Getter public class Furn { private Integer id; private String name; private Double price; }
- 修改HelloController.java
@Controller public class HelloController { @RequestMapping("/hello") @ResponseBody public String hello(){ return "hello, spring boot"; } @Autowired Furn furn; @RequestMapping("/furn") @ResponseBody public Furn furn(){ return furn; } }
- 启动SpringBoot 主程序,测试
如果测试时发现有结果为空,说明properties 文件的属性写错了。
配置绑定还有第2 种方式, 也给小伙伴演示下, 完成测试,效果一样, 注意: 注销@Component 需要在BeanConfig.java( 说明: 也可以是其它配置类) 配置@EnableConfigurationProperties(Furn.class), 否则会提示错误
//@EnableConfigurationProperties(Furn.class)解读 //1、开启Furn 配置绑定功能 //2、把Furn 组件自动注册到容器中 @EnableConfigurationProperties(Furn.class) public class BeanConfig { }
注意事项和细节
1.如果application.properties 有中文, 需要转成unicode 编码写入, 否则出现乱码。可以使用unicode转码工具进行转换。
#设置属性k-v furn01.id=100 furn01.name=soft_chair\u6c99\u53d1!! furn01.price=45678.9
2.使用@ConfigurationProperties(prefix = “furn01”) 会提示如下信息, 但是不会影响使用
- 解决@ConfigurationProperties(prefix = “furn01”) 提示信息, 在pom.xml 增加依赖, 即可
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>