第6章 Spring Boot核心
6.1 基本配置
6.1.1 入口类和@SpringBootApplication SpringBootApplication是Spring Boot的核心注解,是一个组合注解,主要组合了@Configuration、@EnableAutoConfiguration、@ComponentScan。 @EnableAutoConfiguration让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置。 Spring Boot会自动扫描@SpringBootApplication所在类的同级包以及下级包里的Bean。
6.1.2 关闭特定的自动配置 @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class} )
6.1.3 定制Banner 在src/main/resources下新建一个banner.txt。 获取banner
6.1.4 Spring Boot的配置文件 Spring Boot使用一个全局的配置文件application.properties或application.xml,放置在src/main/resources目录或者类路径的/config下。 Spring Boot不仅支持常规的properties配置文件,还支持yaml语言的配置文件。yaml是以数据为中心的语言,在配置数据的时候具有面向对象的特征。 Spring Boot的全局配置文件的作用是对一些默认配置的配置值进行修改。 1.简单示例
server.port=9090 server.context-path=/helloboot上述配置端口改为9090,访问路径改为“/helloboot”
6.1.5 starter pom Spring Boot为我们提供了简化企业级开发绝大多数场景的starter pom,只要使用了应用场景所需要的starter pom,相关的技术配置将会消除,就可以得到Spring Boot为我们提供的自动配置的Bean。
6.1.6 使用xml配置 在实际项目中,如果必须使用xml配置,可以通过@ImportResource来加载xml配置。 @ImportResource({“classpath:some-context.xml”,”classpath:another-context.xml”})
6.2 外部配置 Spring Boot允许使用properties文件、yaml文件或者命令行参数作为外部配置。
6.2.1 命令行参数配置
java -jar xx.jar --server.port=90906.2.2 常规属性配置 在application.properties定义属性,直接使用@Value注入即可。
book.author=peter book.name=spring boot package com.example; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController @SpringBootApplication //@SpringBootApplication是Spring Boot项目的核心注解, //主要目的是开启自动配置。 public class DemoApplication { @Value("${book.author}") private String bookAuthor; @Value("${book.name}") private String bookName; @RequestMapping("/") String index() { return "book name is " + bookName + " and author is " + bookAuthor; } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); //作为项目启动的入口 } }6.2.3 类型安全的配置(基于properties) Spring Boot还提供了基于类型安全的配置方式,通过@ConfigurationProperties将Properties属性和一个Bean及其属性关联,从而实现类型安全的配置。 1.实战
author.name=wyf author.age=32 package com.wisely.ch6_2_3.config; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "author") //1通过@ConfigurationProperties加载properties文件内的配置,通过prefix属性指定properties的配置的前缀, //通过locations指定properties文件的位置。 public class AuthorSettings { private String name; private Long age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getAge() { return age; } public void setAge(Long age) { this.age = age; } } package com.wisely.ch6_2_3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.wisely.ch6_2_3.config.AuthorSettings; @RestController @SpringBootApplication public class Ch623Application { @Autowired private AuthorSettings authorSettings; //1 @RequestMapping("/") public String index(){ return "author name is "+ authorSettings.getName()+" and author age is "+authorSettings.getAge(); } public static void main(String[] args) { SpringApplication.run(Ch623Application.class, args); } }6.3 日志配置 Spring Boot支持Java Util Loggin、Log4J、Log4J2和Logback作为日志框架,默认使用Logback。 配置日志文件: logging.file=D:/mylog/log.log 配置日志级别,格式为logging.level.包名=级别: logging.level.org.springframework.web=DEBUG
6.4 Profile配置 Profile是Spring用来针对不同的环境对不同的配置提供支持的,全局profile配置使用application-{profile}.properties(如application-prod.properties)。 通过在application.properties中设置spring.profiles.active=prod来指定活动的Profile。
1 示例
application-dev.properties文件: server.port=88
application-prod.properties文件: server.port=8888
application.properties文件: spring.profiles.active=prod
6.5 Spring Boot运行原理
Spring Boot自动配置的源码在spring-boot-autoconfigure 的jar包内。 查看当前项目中已启用和未启用的自动配置的报告: * (1)运行jar时增加–debug参数
java -jar xx.jar --debug (2) 在application.properties中设置属性: debug=true6.5.1 运作原理 核心功能是由@EnableAutoConfiguration注解提供的。
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class} ), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class} )} ) public @interface SpringBootApplication { @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({AutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; }AutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法来扫描META-INF\spring.factories
6.5.2 核心注解
@Configuration @ConditionalOnClass({EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class}) @ConditionalOnProperty( prefix = "spring.aop", name = {"auto"}, havingValue = "true", matchIfMissing = true ) public class AopAutoConfiguration { @Configuration @ConditionalOnClass({CacheManager.class}) @ConditionalOnBean({CacheAspectSupport.class}) @ConditionalOnMissingBean( value = {CacheManager.class}, name = {"cacheResolver"} ) @EnableConfigurationProperties({CacheProperties.class}) @AutoConfigureBefore({HibernateJpaAutoConfiguration.class}) @AutoConfigureAfter({CouchbaseAutoConfiguration.class, HazelcastAutoConfiguration.class, RedisAutoConfiguration.class}) @Import({CacheAutoConfiguration.CacheConfigurationImportSelector.class}) public class CacheAutoConfiguration {条件注解: @ConditionalOnBean:当容器里有指定的Bean的条件下。 … @ConditonalOnWebApplication:当前项目是Web项目的条件下。 这些注解都是组合了@Conditional元注解,只是使用了不同的条件。
6.5.3 实例分析
6.5.4 实战(后面回来看) 自己写一个starter pom。
package com.wisely.spring_boot_starter_hello; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix="hello") //在application.properties配置的时候前缀是hello.msg public class HelloServiceProperties { private static final String MSG = "world"; private String msg = MSG; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } package com.wisely.spring_boot_starter_hello; public class HelloService { private String msg; public String sayHello() { return "Hello" + msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } } package com.wisely.spring_boot_starter_hello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @EnableConfigurationProperties(HelloServiceProperties.class)//开启属性注入 @ConditionalOnClass(HelloService.class)//当HelloService在类路径的条件下 @ConditionalOnProperty(prefix="hello",value="enabled",matchIfMissing = true)//如果没有设置则默认为true,即条件符合 public class HelloServiceAutoConfiguration { @Autowired private HelloServiceProperties helloServiceProperties; @Bean//使用Java配置的方式配置HelloService这个Bean @ConditionalOnMissingBean(HelloService.class)//当容器中没有这个Bean的时候新建Bean public HelloService helloService() { HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }src/main/resources/META-INF/spring.factories的配置: org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.wisely.spring_boot_starter_hello.HelloServiceAutoConfiguration
上述完成spring-boot-starter-hello的开发,使用“mvn install”安装到本地库。
使用该starter pom:
加入依赖
<dependency> <groupId>com.wisely</groupId> <artifactId>spring-boot-starter-hello</artifactId> <version>0.0.1</version> </dependency> package com.wisely.ch6_5; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.wisely.spring_boot_starter_hello.HelloService; @RestController @SpringBootApplication public class Ch65Application { @Autowired HelloService helloService; @RequestMapping("/") public String index() { return helloService.sayHello(); } public static void main(String[] args) { SpringApplication.run(Ch65Application.class, args); } }