一、SpringBoot配置
1、配置文件
SpringBoot使用一个全局的配置文件,配置文件的名称是固定的
- application.properties
- 语法结构:key=value
- application.yml
- 语法结构:key:(空格)value
配置文件的作用:修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了
# 对空格的要求非常高 name: yanheng # 对象 student1: name: cyh age: 14 # 行内写法 student2: {name: cyh, age: 14} # 数组 pets: - cat - dog - pig pets2: [cat,dog,pig]
server.port=8081 student.name=cyh student.age=14
2、给属性赋值的几种方式
@ConfigurationProperties
将配置文件中配置的每一个属性的值,映射到这个组件中;
告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定
参数prefix=”person“:将配置文件中的person下面的所有属性一一对应
只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
@Repository @ConfigurationProperties(prefix = "person") public class Person { private Integer id; private String name; private String hello; private Dog dog; }
person: id: ${random.uuid} name: cyh hello: hha dog: name: ${person.hello:hello}旺财 age: 3
PropertySource
@PropertySource(value = "classpath:application.properties") public class Dog { @Value("${name}") private String name; private Integer age; }
name=cccc
引入environment
@Resource private Environment env; @RequestMapping("/hello") public String hello(){ String property = env.getProperty("server.port"); System.out.println(property); return "index"; }
对比
- @ConfigurationPropertie只需要写一次即可,value则需要每一个字段都添加
- yaml支持松散绑定
- yaml里last-name和java里的lastName可以绑定
- yaml支持JSR303数据校验
- 可以在字段增加一层过滤器验证,保证数据的合法性
- yaml支持复杂类型封装,可以封装对象
@Repository @ConfigurationProperties(prefix = "person") @Validated//JSR303数据校验 public class Person { private String id; @Email(message = "邮箱错了!!")//数据不合法则控制台提示邮箱错了 private String name; private String hello; private Dog dog;
3、多环境配置及配置文件位置
优先级
properties>yaml
- 项目路径下的config文件夹配置文件
- 项目路径下的配置文件
- 资源路径下的config文件夹配置文件
- 资源路径下的配置文件
打成jar包之后不会包含项目根路径的config文件夹(不属于springboot的基本项目结构),故使用jar包运行时项目根路径下的config中的配置会失效
多环境配置
默认执行application.properties
- profile用来完成不同环境下,配置动态切换功能的
- profile配置方式
- 多profile文件方式:提供多个配置文件,每一个代表一种环境
- application-dev.properties/yaml开发环境
- application-pro.properties/yaml生产环境
- application-test.properties/yaml测试环境
- yaml多文档方式
- 在yaml中使用—分隔不同配置
- 通过spring.config.activate.on-profile:pro/dev/test区分各个分区
3.profile的激活方式
- 配置文件:在配置文件(application.properties或yaml中的独立分区)中配置:spring.profiles.active=dev
- 虚拟机参数:在VM options指定:-Dspring.profiles.active=dev
- 命令行参数:java-jar xxx.jar --spring.profiles.active=dev
使用外部配置文件
- 在命令行参数:java-jar xxx.jar --spring.config.location=e://application.properties
- 配置文件放在和jar包同级的目录,运行jar包时配置文件会被自动读取
- 配置文件放在和jar包同级的config文件夹下,运行jar包时配置文件会被自动读取,优先级大于上者
4、整合其他框架
1)整合Junit
- 搭建SpringBoot工程
- 引入starter-test起步依赖
- 编写测试类
4.添加测试相关注解
- @RunWith(SpringRunner.class)
- @SpringBootTest(classes=启动类.class)
5.编写测试方法
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency>
@RunWith(SpringRunner.class) @SpringBootTest(classes = SpringbootApplication.class) public class UserServiceTest { @Autowired private UserService userService; @Test public void testAdd(){ userService.add(); } }
@SpringBootTest中的classes参数为springboot启动类的字节码文件
如果该Test文件所在的包和springboot启动类所在包一致或为其子包(都为cn.ken),则可以省略该参数
2)整合redis
实现步骤:
- 搭建SpringBoot工程
- 引入redis起步依赖
- 配置redis相关属性(默认本机6379端口)
- 注入RedisTemplate模板
- 编写测试方法,测试
@SpringBootTest class SpringbootRedisApplicationTests { @Autowired private RedisTemplate redisTemplate; @Test void testSet() { redisTemplate.boundValueOps("name").set("cyh"); } @Test void testGet() { Object name = redisTemplate.boundValueOps("name").get(); System.out.println(name); } }
需先运行redis-server.exe
3)整合MyBatis
- 搭建SpringBoot工程
- 引入MyBatis起步依赖,添加mysql驱动
- 编写DataSource和MyBatis相关配置
- 定义表和实体类
- 编写dao和mapper文件/纯注解开发
- 测试
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?serverTimeZone=UTC username: root password: 129496 mybatis: #config-location: #指定mybatis的核心配置文件 mapper-locations: classpath:mapper/*Mapper.xml #mapper映射文件地址 type-aliases-package: cn.ken.springbootmybatis.domain
// 注解方式(也不需要上面yaml的配置) @Mapper public interface UserMapper { @Select("select * from user") List<User> findAll(); }
// 配置文件方式 @Mapper public interface UserXmlMapper { List<User> findAll(); }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="cn.ken.springbootmybatis.mapper.UserXmlMapper"> <select id="findAll" resultType="user"> select * from user; </select> </mapper>
// 测试 @SpringBootTest class SpringbootMybatisApplicationTests { @Resource private UserMapper userMapper; @Resource private UserXmlMapper userXmlMapper; @Test public void testUserMapper(){ System.out.println(userMapper.findAll()); } @Test public void testUserMapper2(){ System.out.println(userXmlMapper.findAll()); } }
二、SpringBoot自动配置
1、condition
Condition是在Spring4.0增加的条件判断功能,通过这个功能可以实现选择性创建Bean的操作
public class ClassCondition implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { boolean flag = true; try { Class<?> aClass = Class.forName("redis.clients.jedis.Jedis"); } catch (ClassNotFoundException e) { e.printStackTrace(); flag = false; } return flag; } }
如果已经导入了Jedis坐标,则返回true,否则返回false
@Configuration public class UserConfig { @Bean @Conditional(ClassCondition.class) public User user(){ return new User(); } }
参数是一个实现了Condition接口的类,只有参数ClassCondition中的matches方法返回true时才创建
@Bean返回的bean的id为函数名
@SpringBootApplication public class SpringbootMybatisApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(SpringbootMybatisApplication.class, args); Object user = run.getBean("user"); System.out.println(user); } }
@ConditionalOnClass等注解则是在@Conditional注解外面再包一层,传入需要的类的字节码文件,而在Conditional注解的OnClassCondition类上通过反射(该类实现matches方法,其中有两个参数context和metadata,metadata就可以通过反射获取到注解的属性)获取这些需要的字节码文件,来判断是否满足创建bean的需求,实现动态判断。
SpringBoot提供的常用条件注解:
- ConditionalOnProperty(name=“x”, havingValue=“xx”):判断配置文件中是否有对应属性和值才初始化Bean
- ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
- ConditionalOnMissingBean:判断环境中没有对应的Bean才初始化Bean
2、切换内置Web服务器
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency>
排除内置tomcat,引入jetty依赖
3、Enable*注解
SpringBoot提供了很多Enable开头的注解,这些注解都是用于动态开启某些功能的,而其底层原理是使用@Import注解导入一些类配置类,实现Bean的动态加载。
@SpringBootApplication注解中包含的@ComponentScan的扫描范围为当前类所在包及其子包,故导入其他依赖中的bean无法直接使用,因为对应的bean所在的包不是当前包所在包的子包。
为了解决这个问题可以采取:
- 增加@Component扫描对应bean的包
- 使用@Import注解加载对应的类,这些类都会被Spring创建并放入IOC容器
- 定义@Enable*注解对@Import注解进行封装
@Import
@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中,@Import提供了四种用法:
导入Bean
导入配置类(配置类里注册的Bean也会被导入)
导入ImportSelector实现类,一般用于加载配置文件中的配置类
导入ImportBeanDefinitionRegistrar实现类
EnableAutoConfiguration注解
@EnableAutoConfiguration注解内部使用@Import(AutoConfigurationImportSelector.class)来加载配置类(selectImports方法返回要加载的类的字符串数组)
配置文件位置:META/spring.properties(SpringFactoriesLoader类去加载),该配置文件中定义了大量的配置类,当SpringBoot应用启动时,会自动加载这些配置类,初始化Bean
并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足的Bean
4、自动装配原理
SpringBoot启动会加载大量的自动配置类,自动装配类中配置了一些组件,配置时从properties类中获取属性,我们只需要在配置文件中指定这些属性的值即可。
xxxAutoConfiguration:自动装配类
xxxProperties:封装配置文件中相关属性
可以通过debug=true查看哪些配置类生效,哪些没有生效
@Configuration( proxyBeanMethods = false ) @ConditionalOnClass({MongoClient.class, MongoTemplate.class}) @EnableConfigurationProperties({MongoProperties.class}) @Import({MongoDataConfiguration.class, MongoDatabaseFactoryConfiguration.class, MongoDatabaseFactoryDependentConfiguration.class}) @AutoConfigureAfter({MongoAutoConfiguration.class}) public class MongoDataAutoConfiguration { public MongoDataAutoConfiguration() { } }
@Configuration:配置类
@ConditionalOnClass:满足具有后面类地条件才生效(即导入了该依赖)
@EnableConfigurationProperties({MongoProperties.class}):封装配置文件
@Import:导入其他配置类
SpringBoot基础(二)+https://developer.aliyun.com/article/1390593?spm=a2c6h.13148508.setting.15.7e0d4f0e107vfb