SpringBoot配置文件的自动装配
首先SpringBoot的@SpringBootApplication注解可以自动装配项目(包括jar文件)根路径下的META-INF目录下的spring.factories文件的org.springframework.boot.autoconfigure.EnableAutoConfiguration内的类,所以我们根据这个原理来实现自定义的自动装配。
首先我们创建一个springboot项目:
项目在maven的坐标信息如下
<groupId>com.entor</groupId>
<artifactId>demo01-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
第一步我们创建一个实体类
该实体类的初始化从配置文件中取值
@ConfigurationProperties作用:可以从配置文件中读取前缀为entor.user的数据封装到对应名称的属性中。
@Data:IoC容器为属性赋值和注入到其他地方时需要get和set方法,@Data自动生成get和set等方法。
@Data
@ConfigurationProperties(prefix = "entor.user")//该注解必须在IoC容器中才有作用,否则该注解会报红(先不管)
public class UserProperties {
private Integer id;
private String name;
private Integer age;
}
第二步我们创建一个服务层,该服务层我们在配置类中交给Ioc容器管理(IoC的对象创建和注入需要get和set方法和构造方法)
public class UserService {
private UserProperties userProperties;
public UserService() {
}
public UserService(UserProperties userProperties) {
this.userProperties = userProperties;
}
public String getName() {
return userProperties.getName();
}
public UserProperties getUserProperties() {
return userProperties;
}
}
第三步我们创建一个配置类也就是我们的IoC容器,来负责创建对象和注入
@Configuration//代表该类是一个IoC容器
@EnableConfigurationProperties({UserProperties.class})//把标注@ConfigurationProperties的类加入Bean容器
public class UserAutoConfigurator {
@Bean
//当用户端配置属性entor.user.enable=true的时候才把该对象加入bean容器
@ConditionalOnProperty(prefix = "entor.user",name = "enabled",havingValue = "true")
public UserService userService(UserProperties userProperties) {
return new UserService(userProperties);
}
}
接下来我们在根路径(src.main.resources目录)创建一个目录META-INF在该目录下创建文件spring.factories,内容为:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.entor.config.UserAutoConfigurator
这样我们在启动项目时,SpringBoot就会因为自动装备的原理去加载我们的com.entor.config.UserAutoConfigurator类。
接下来建立新的module项目(建立springboot-web项目)然后引入我们上边项目的maven坐标。
在项目下写入一个控制层
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/getName")
public String getName() {
return userService.getName();
}
}
接下来在配置文件写上我们初始化的值
entor:
user:
id: 1
name: 李四
age: 50
enabled: true
接下来就可以进行测试了。
使用注解来实现自动装配
创建新的模块也是一个springboot项目
核心注解@Import({Class.class})加载我们自定义的IoC容器
第一步我们定义实体类
@Data
@ConfigurationProperties(prefix = "entor.role")
public class RoleProperties {
private Integer id;
private String name;
}
第二步我们创建服务层
public class RoleService {
private RoleProperties roleProperties;
public RoleService() {
}
public RoleService(RoleProperties roleProperties) {
this.roleProperties = roleProperties;
}
public String getName() {
return roleProperties.getName();
}
}
第三步写上我们的配置类来负责创建对象和注入
和上边的区别在于少了@Configuration,该注解是定义该类是一个IoC容器来负责帮助我们创建和注入对象。
@EnableConfigurationProperties({RoleProperties.class})
public class RoleConfiguration {
@Bean
@ConditionalOnProperty(prefix = "entor.role",name = "enabled",havingValue = "true")
public RoleService roleService(RoleProperties roleProperties){
return new RoleService(roleProperties);
}
}
上边是用了springboot的自动加载特定文件来加载这个类的,那么我们创建一个注解来帮助我们加载这个类。
第三步自定义注解来加载指定类
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({RoleConfiguration.class})//通过注解的方式配置是否注入bean容器中
public @interface EnableRoleService {
}
接下来和上面一样在springboot-web模块中导入该项目的坐标来测试。
在测试的项目中创建控制层
@RestController
public class RoleController {
@Autowired
private RoleService roleService;
@RequestMapping("/getRoleName")
public String getRoleName() {
return roleService.getName();
}
}
在启动类上用我们自定义的注解来导入我们的配置类
@SpringBootApplication
@EnableSysService
public class Springboot0426Application {
public static void main(String[] args) {
SpringApplication.run(Springboot0426Application.class, args);
}
}
配置文件写上数据
role:
id: 1
name: 管理员
age: 50
enabled: true
至此完成配置可以开始测试。
@Conditional的使用
这个注解用在配置类的方法上,决定一个bean对象是否创建。与其相关的接口为org.springframework.context.annotation.Condition。
接下来相当于掩饰使用Impor()注解来装配IoC容器,主要掩饰@Conditional的作用
第一步定义一个service的接口
public interface SysService {
/**
* 获取当前操作系统名称
* @return
*/
public String getSysName();
}
该接口的个实现类为:
第一个实现类
public class WinSystemService implements SysService {
@Override
public String getSysName() {
return "Windows";
}
}
第二个实现类
public class LinuxSystemService implements SysService {
@Override
public String getSysName() {
return "Linux";
}
}
第二步定义实现Condition接口的两个类
第一个类
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getProperty("os.name").contains("Linux");
}//检测系统是否是Linux操作系统,是返回true
}
第二个类
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getProperty("os.name").contains("Windows");
}//检测系统是否是Windows操作系统,是返回true
}
这两个类决定了是否生成bean。
第三步就是配置类
public class SysConfig {
@Bean
@Conditional({WindowsCondition.class})//我的电脑是windows操作系统所以这里返回的true这个bean对象可以生成
public SysService getWinSysService() {
return new WinSystemService();
}
@Bean
@Conditional({LinuxCondition.class})//这个返回的就是false这个bean对象不生
public SysService getLinuxSysService() {
return new LinuxSystemService();
}
}
第四部自定义注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SysConfig.class})
public @interface EnableSysService {
}
使用时在springboot-web模块中写上这个项目的坐标
写上一个控制层:
@RestController
public class RoleController {
@Autowired
private RoleService roleService;
@RequestMapping("/getRoleName")
public String getRoleName() {
return roleService.getName();
}
}
注意在启动上加上我们自定义的注解来使我们的配置类生效
@SpringBootApplication
@EnableRoleService
@EnableSysService
public class Springboot0426Application {
public static void main(String[] args) {
SpringApplication.run(Springboot0426Application.class, args);
}
}
至此完成配置