文章目录
读取配置文件内容
- @Value
@Value("${name}")
private String name;
@Value("${person.name}")
private String name2;
- Environment
@Autowired
private Environment env;
System.out.println(env.getProperty("person.name"));
System.out.println(env.getProperty("address[0]"));
- @ConfigurationProperties
创建对象与yml配置文件的内容进行绑定
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private int age;
private String[] address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String[] getAddress() {
return address;
}
public void setAddress(String[] address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
person:
name: zhangsan
age: 20
address:
- beijing
- shanghai
profile
在开发SpringBoot应用时,通常同一套程序会被安装到不同环境,比如开发、测试、生产等。不同环境下的配置不同,若每次打包时都要修改配置文件会非常麻烦。profile功能就是来进行动态配置切换的
-
profile配置方式
-
多profile文件方式:提供多个配置文件,每个代表一个环境
- application-dev.properties/yml 开发环境
- application-test.properties/yml 测试环境
- application-pro.properties/yml 生产环境
-
yml多文档方式
- 在yml中使用 — 分隔不同配置
--- server: port: 8081 spring: profiles: dev --- server: port: 8082 spring: profiles: test --- server: port: 8083 spring: profiles: pro --- spring: profiles: active: dev
-
-
profile激活方式
- 配置文件:在配置文件中配置
spring.profiles.active=dev
- 虚拟机参数:在VM options指定
-Dspring.profiles.active=dev
- 命令行参数
java -jar xxx.jar --spring.profiles.active=dev
内部配置加载顺序
SpringBoot程序启动时,会从以下位置加载配置文件
- file:./config/:当前项目的/config目录下
- file:./:当前项目的根目录
- classpath:/config/:classpath的/config目录
- classpath:/:classpath的根目录
加载顺序为上文的排列顺序,高优先级配置的属性会生效
外部配置加载顺序
参考Springboot加载外部配置文件的方法_new defaultresourceloader().getresource-CSDN博客
SpringBoot原理分析
SpringBoot自动配置
Condition
通过Conditon这个功能,可以实现选择性的创建Bean操作
-
自定义条件
-
定义条件类:自定义类实现Condition接口,重写matches方法,在matches方法中进行逻辑判断,返回boolean值。以下为matches方法的两个参数
- context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。具体来说,通过context对象,可以获取环境、IoC容器、ClassLoader对象等等
- metadata:元数据对象,用于获取注解属性
//获取注解属性值value Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
-
判断条件:在初始化Bean时,使用@Conditional(条件类.class)注解
-
-
SpringBoot提供的常用条件注解
- ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
- ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
- ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean
切换内置web服务器
SpringBoot的web环境中默认使用tomcat作为内置服务器,其实SpringBoot提供了4种内置服务器供选择,我们可以修改maven工程中的pom配置文件进行很方便的切换
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除tomcat依赖-->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入jetty的依赖-->
<dependency>
<artifactId>spring-boot-starter-jetty</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
@Enable*注解
SpringBoot提供了很多Enable开头的注解,这些注解都是用于动态启用某些功能的。其底层原理是使用@Import注解导入一些配置类,实现动态加载
在一个工程中想使用其他工程定义的bean时,可以采用以下几种方法
- 使用@ComponentScan扫描bean对应的包
@ComponentScan("com.itheima.config")
- 使用@Import注解,加载类。这些类都会被Spring创建并放入IoC容器
@Import(UserConfig.class)
- 可以对Import注解进行封装
自定义封装的EnableUser注解类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UserConfig.class)
public @interface EnableUser {
}
调用@EnableUser注解
@EnableUser
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
Object user = context.getBean("user");
System.out.println(user);
}
}
@Import注解
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IoC容器中。而@Import提供4种用法
- 导入Bean
下面的代码直接导入Userbean
@Import(User.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
// 按类型获取,不能按名称获取,若使用按名称获取可能会找不到
User user = context.getBean(User.class);
System.out.println(user);
}
}
- 导入配置类
@Import(UserConfig.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
// UserConfig配置类中有两个bean:User和Role,均能被获取到
User user = context.getBean(User.class);
System.out.println(user);
Role role = context.getBean(Role.class);
System.out.println(role);
}
}
对于这种导入方法,配置类UserConfig上面的注解@Configuration是可以省略的
//@Configuration
public class UserConfig {
@Bean
public User user() {
return new User();
}
@Bean
public Role role() {
return new Role();
}
}
- 导入ImportSelector实现类,一般用于加载配置文件中的类
实现类如下
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 复写接口方法,导入两个bean:User和Role
return new String[]{"com.itheima.domain.User", "com.itheima.domain.Role"};
}
}
再导入实现类即可
@Import(MyImportSelector.class)
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
// MyImportSelector实现类中有两个bean:User和Role,均能被获取到
User user = context.getBean(User.class);
System.out.println(user);
Role role = context.getBean(Role.class);
System.out.println(role);
}
}
这种方式和上一种方式类似,但这种方式在配置实现类中是以字符串实现的,所以可以用这个方式加载一些配置文件的bean
- 导入ImportBeanDefinitionRegistrar实现类
创建ImportBeanDefinitionRegistrar的实现类
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 获取User类的定义
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
// 注册以user为名称,User类的定义为定义的bean
registry.registerBeanDefinition("user", beanDefinition);
}
}
导入ImportBeanDefinitionRegistrar实现类
@Import({MyImportBeanDefinitionRegistrar.class})
public class SpringbootEnableApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);
// ImportBeanDefinitionRegistrar中只有User的bean,没有Role的bean
// 所以输出role时会报错
User user = context.getBean(User.class);
System.out.println(user);
Role role = context.getBean(Role.class);
System.out.println(role);
}
}
@EnableAutoConfiguration注解
- @EnableAutoConfiguration注解内部使用@Import(AutoConfigurationImportSelector.class)来加载配置类
- 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当SpringBoot应用启动时,会自动加载这些配置类,初始化bean
- 并不是所有的bean都会被初始化,在配置类中使用Condition来加载满足条件的bean
说明:spring.factories是SpringBoot中用于自动配置的一种机制,位于META-INF目录下。spring.factories文件采用了 Java properties 文件的格式,每一行表示一个自动配置类及其对应的条件