基本配置
入口类和@SpringBootApplication
SpringBoot通常有一个名为*Application的入口类,入口类里面有一个main方法,这个main方法其实就是一个标准的Java应用的入口方法。在main方法中使用SpringApplication.run(Application.class, args),启动SpringBoot应用项目。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
ApplicationContext applicationContext=SpringApplication.run(Application.class, args);
SpringContextUtil.setApplicationContext(applicationContext);
}
}
@SpringBootApplication是Spring Boot的核心注解,它是一个组合注解,源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Configuration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
Class<?>[] exclude() default {};
String[] excludeName() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
@SpringBootApplication注解主要组合了@Configuration、@EnableAutoConfiguration、@ComponentScan;若不使用@SpringBootApplication注解,则可以在入口类上直接使用@Configuration、@EnableAutoConfiguration、@ComponentScan。
其中,@EnableAutoConfiguration让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置。
例如,添加了spring-boot-starter-web依赖,会自动添加Tomcat和SpringMVC的依赖,那么SpringBoot会对Tomcat和SpringMVC进行自动配置。
又如,添加了spring-boot-starter-data-jpa依赖,SpringBoot会自动进行JPA相关的配置。
Spring Boot会自动扫描@SpringBootApplication所在类的同级包以及下级包里的Bean(若为JPA项目还可以扫描标注@Entity的实体类)。建议入口类放置的位置在groupId+arctifactId组合的包名下。
关闭特定的自动配置
关闭特定的自动配置应该使用@SpringBootApplication注解的exclude参数,例如:
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
定制Banner
1、修改Banner
在Spring Boto启动的时候会有一个默认启动图案,如图:
(2)在src/main/resources下新建一个banner.txt。
(3)通过http://patorjk.com/software/taag网站生成字符,将网站生成的字符复制到banner.txt中。
(4)这时再启动程序,图案变成:
2、关闭Banner
将main里面的内容修改为:
public static void main(String[] args) {
SpringApplication app=new SpringApplication(Application.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
SpringBoot的配置文件
SpringBoot使用一个全局的配置文件application.properties或application.yml,放置在src/main/resources目录下或者类路径的/config下。
SpringBoot不仅支持常规的properties配置文件,还支持yaml语言的配置文件。yaml是以数据为中心的语言,在配置数据的时候具有面向对象的特征。
SpringBoot的全局配置文件的作用是对一些默认配置的配置值进行修改。
1、简单示例
将Tomcat的默认端口号8080修改为9090,并将默认的访问路径“/”修改为“/helloboot”。
可以在application.properties中添加:
server.port=9090
server.context-path=/helloboot
或在application.yml中添加:
server:
port: 9090
contextPath: /helloboot
从上面的配置可以看出,在SpringBoot中,context-path、contextPath形式是通用的。
starter pom
Spring Boot为我们提供了简化企业级开发绝大多数场景的starter pom,只要使用了应用场景所需要的starter pom,相关的技术配置将会消除,就可以得到Spring Boot为我们提供的自动配置的Bean。
常用的几个starter pom
(官方starter pom)
名称 | 描述 |
spring-boot-starter | Spring Boot核心starter,包含自动配置、日志、yaml配置文件的支持 |
spring-boot-actuator | 准生产特性,用来监控和管理应用 |
spring-boot-starter-aop | 使用spring-aop和AspectJ支持面向切面编程 |
spring-boot-starter-data-jpa | 对JPA的支持,包含spring-data-jpa、spring-orm和Hibernate |
spring-boot-starter-data-mongodb | 通过spring-data-mongodb,对MongoDB进行支持 |
spring-boot-starter-jdbc | 对JDBC数据库的支持 |
spring-boot-starter-redis | 对键值对内存数据库Redis的支持,包含spring-redis |
spring-boot-starter-security | 对spring-security的支持 |
spring-boot-starter-web | 对Web项目开发的支持,包含Tomcat和spring-webmvc |
spring-boot-starter-Tomcat | Spring Boot默认的Servlet容器Tomcat |
spring-boot-starter-log4j | 支持使用Log4J日志框架 |
spring-boot-starter-websocket | 对WebSocket开发的支持 |
使用xml配置
Spring Boot提倡零配置,即无xml配置,但是在实际项目中,可能有一些特殊要求你必须使用xml配置,这时我们可以通过Spring提供的@ImportResource来加载xml配置。例如:
@ImportResource({"classpath: some-context.xml", "classpath: another-context.xml"})
外部配置
Spring Boot允许使用properties文件、yaml文件或者命令行参数作为外部配置。
命令行参数配置
Spring Boot可以是基于jar包运行的,打成jar包的程序可以直接通过下面命令运行:
java -jar xx.jar
可以通过以下命令修改Tomcat端口号:
java -jar xx.jar --server.port=9090
常规属性配置
在常规Spring环境下,注入properties文件里的值的方式——通过@PropertySource指明properties文件的位置,然后通过@Value注入值。
在Spring Boot里,我们只需在application.properties定义属性,直接使用@Value注入即可。
(1)application.properties增加属性:
server:
servlet:
context-path : /hellobook
port : 8080
#添加属性
book:
author: xiaoding
name: zhuxian
(2)修改入口类
package com.example.SpringBootDemo1;
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
public class SpringBootDemo1Application {
@Value("${book.author}")
private String bookAuthor;
@Value("${book.name}")
private String bookName;
@RequestMapping("/")
String index() {
return "作者:"+bookAuthor+" 书名:"+bookName;
}
public static void main(String[] args) {
SpringApplication.run(SpringBootDemo1Application.class, args);
}
}
(3)运行,访问:http://localhost:8080/hellobook/
类型安全的配置(基于properties)
使用@Value注入每个配置在实际项目中会显得格外麻烦,因为配置通常会是许多个,使用上面的方式要使用@Value注入很多次。
Spring Boot提供了基于类型安全的配置方式,通过@ConfigurationProperties将Properties属性和一个Bean及其属性关联,从而实现类型安全的配置。
(1)新建Spring Boot项目
(2)添加配置,即在application.yml上添加:
server:
servlet:
context-path : /helloAuthor
port : 8080
#添加属性
author:
name: xiaoding
age: 32
也可以新建一个properties或者yml文件,这就需要在@ConfigurationProperties的属性locations里指定properties的位置,且需要在入口类上配置。
(3)类型安全的Bean,代码如下:
package com.example.entity;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix="author")
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;
}
}
代码解释
通过@ConfigurationProperties加载properties或yml文件内的配置,通过prefix属性指定properties的配置的前缀,通过locations指定properties文件的位置,但新版本中废除了location属性,故只写前缀,默认读取application.yml中数据。
(4)检验代码
package com.example.SpringBootDemo1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.example.entity.AuthorSettings;
@RestController
@SpringBootApplication
//指定实体类所在的包,如果在同一个包下,就不需要写了
@ComponentScan(basePackages= {"com.example.entity"})
public class SpringBootDemo1Application {
@Autowired
private AuthorSettings aSettings;
@RequestMapping("/")
public String home() {
return "姓名: "+aSettings.getName()+" 年龄: "+aSettings.getAge();
}
public static void main(String[] args) {
SpringApplication.run(SpringBootDemo1Application.class, args);
}
}
(5)运行,访问:http://localhost:8080/helloAuthor/
日志配置
Spring Boot支持Java Util Logging、Log4J、Log4J2和Logback作为日志框架,无论使用哪种日志框架,Spring Boot已为当前使用日志框架的控制台输出及文件输出做好了配置。
默认情况下,Spring Boot使用Logback作为日志框架。
配置日志级别:
logging.file=D:/mylog/log.log
配置日志文件,格式为logging.level.包名=级别:
logging.level.org.springframework.web= DEBUG
Profile配置
Profile是Spring用来针对不同的环境对不同的配置提供支持的,全局Profile配置使用application-{profile}.properties(如application-prod.properties)。
通过在application.properties中设置spring.profiles.active=prod来指定活动的Profile。
假如分为生产(prod)和开发(dev)环境,生产环境下端口号为80,开发环境下端口为8888.
(1)新建Spring Boot项目
(2)生产和开发环境下的配置文件如下:
application-prod.properties:
server-port=80
application-dev.properties:
server-port=8888
项目目录结构如图:
(3)运行
application.properties增加:
spring.profiles.active=dev
启动程序结果为:
修改application.properties:
spring.profiles.active=prod
运行结果变为:
SpringBoot运行原理
Spring4.x提供了基于条件来配置Bean的能力,Spring Boot的实现也是基于这一原理的。
Spring Boot关于自动配置的源码在spring-boot-autoconfugure-1.3.0.x.jar内,主要包含了如图所示的配置。
若想知道Spring Boot为我们做了哪些自动配置,可以查看这里的源码。
可以通过下面三种方式查看当前项目中已启用和未启用的自动配置的报告。
(1)运行jar时增加--debug参数:
(2)在application.yml中设置属性:
(3)在STS中设置,Run->Run Configurations...,如图所示。
此时启动,可在控制台输出。已启用的自动配置为:
未启用的自动配置为:
运作原理
关于Spring Boot的运作原理,回归到@SpringBootApplication注解上来,这个注解是一个组合注解,它的核心功能是由@EnableAutoConfiguration注解提供的。
@EnableAutoConfiguration注解的源码:
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.SpringFactoriesLoader;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
这里的关键功能是@Import注解导入的配置功能,EnableAutoConfigurationImportSelector使用SpringFactoriesLoader.loadFactoryNames方法来扫描具有META-INF/spring.factories文件的jar包,而我们的spring-boot-autoconfigure-1.3.0.x.jar里就有一个spring.factories文件,此文件中声明了有哪些自动配置,如图所示。
核心注解
打开上面任意一个AutoConfiguration文件,一般都有下面的条件注解,在spring-boot-autoconfigure-1.3.0.x.jar的org.springframework.boot.autoconfigure.condition包下,条件注解如下。
@ConditionalOnBean:当容器里有指定的Bean的条件下。
@ConditionalOnClass:当类路径下有指定的类的条件下。
@ConditionalOnExpression:基于SpEL表达式作为判断条件。
@ConditionalOnJava:基于JVM版本作为判断条件。
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置。
@ConditionalOnMissingBean:当容器里没有指定Bean的情况下。
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下。
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下。
@ConditionaOnProperty:指定的属性是否具有指定的值。
@ConditionalOnResource:类路径是否有指定的值。
@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选的Bean。
@ConditionalOnWebApplication:当前项目是Web项目的条件下。
这些注解都是组合了@Conditional元注解,只是使用了不同的条件(Condition)。
下面简单分析一下@ConditionalOnWebApplication注解。
package org.springframework.boot.autoconfigure.condition;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Conditional;
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnWebApplicationCondition.class)
public @interface ConditionalOnWebApplication {
}
从源码可以看出,此注解使用的条件时OnWebApplicationCondition,下面我们看看这个条件是如何构造的:
package org.springframework.boot.autoconfigure.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StandardServletEnvironment;
@Order(Ordered.HIGHEST_PRECEDENCE + 20)
class OnWebApplicationCondition extends SpringBootCondition {
private static final String WEB_CONTEXT_CLASS = "org.springframework.web.context."
+ "support.GenericWebApplicationContext";
@Override
public ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata) {
boolean webApplicationRequired = metadata
.isAnnotated(ConditionalOnWebApplication.class.getName());
ConditionOutcome webApplication = isWebApplication(context, metadata);
if (webApplicationRequired && !webApplication.isMatch()) {
return ConditionOutcome.noMatch(webApplication.getMessage());
}
if (!webApplicationRequired && webApplication.isMatch()) {
return ConditionOutcome.noMatch(webApplication.getMessage());
}
return ConditionOutcome.match(webApplication.getMessage());
}
private ConditionOutcome isWebApplication(ConditionContext context,
AnnotatedTypeMetadata metadata) {
if (!ClassUtils.isPresent(WEB_CONTEXT_CLASS, context.getClassLoader())) {
return ConditionOutcome.noMatch("web application classes not found");
}
if (context.getBeanFactory() != null) {
String[] scopes = context.getBeanFactory().getRegisteredScopeNames();
if (ObjectUtils.containsElement(scopes, "session")) {
return ConditionOutcome.match("found web application 'session' scope");
}
}
if (context.getEnvironment() instanceof StandardServletEnvironment) {
return ConditionOutcome
.match("found web application StandardServletEnvironment");
}
if (context.getResourceLoader() instanceof WebApplicationContext) {
return ConditionOutcome.match("found web application WebApplicationContext");
}
return ConditionOutcome.noMatch("not a web application");
}
}
从isWebApplication方法可以看出,判断条件是:
(1)GenericWebApplicationContext是否在类路径中;
(2)容器里是否有名为session的scope;
(3)当前容器的Environment是否为StandardServletEnvironment;
(4)当前的ResourceLoader是否为WebApplicationContext(ResourceLoader是ApplicationContext的顶级接口之一);
(5)我们需要构造ConditionOutcome类的对象来帮助我们,最终通过ConditionOutCome.isMatch()方法返回布尔值来确定条件。
实例分析
在了解了Spring Boot的运作原理和主要的条件注解后,现在来分析一个简单的Spring Boot内置的自动配置功能:http的编码配置。
我们在常规项目中配置http编码的时候是在web.xml里配置一个filter,如:
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
自动配置要满足两个条件:
(1)能配置CharacterEncodingFilter这个Bean;
(2)能配置encoding和forceEncoding这两个参数。
1.配置参数
Spring Boot的自动配置也是基于类型安全的配置实现的,这里的配置类可以在application.properties中直接设置,源码如下:
package com.cn.demo.test;
import java.nio.charset.Charset;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.http.encoding")
public class HttpEncodingProperties {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Charset charset = DEFAULT_CHARSET;
private boolean force = true;
public Charset getCharset() {
return this.charset;
}
public void setCharset(Charset charset) {
this.charset = charset;
}
public boolean isForce() {
return force;
}
public void setForce(boolean force) {
this.force = force;
}
}
代码解释
①在application.properties配置的时候前缀是spring.http.encoding;
②默认编码方式为UTF-8,若修改可使用spring.http.encoding.charset=编码;
③设置forceEncoding,默认为true,若修改可使用spring.http.encoding.force=false。
2.配置Bean
通过调用上述配置,并根据条件配置CharacterEncodingFilter的Bean,我们来看看源码:
package com.cn.demo.test;
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.boot.web.servlet.filter.OrderedCharacterEncodingFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
@Configuration
@EnableConfigurationProperties(HttpEncodingProperties.class) //1
@ConditionalOnClass(CharacterEncodingFilter.class) //2
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) //3
public class HttpEncodingAutoConfiguration {
@Autowired
private HttpEncodingProperties httpEncodingProperties;
@Bean //4
@ConditionalOnMissingBean(CharacterEncodingFilter.class) //5
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.httpEncodingProperties.getCharset().name());
filter.setForceEncoding(this.httpEncodingProperties.isForce());
return filter;
}
}
代码解释
①开启属性注入,通过@EnableConfigurationProperties声明,使用@Autowired注入;
②当CharacterEncodingFilter在类路径的条件下;
③当设置spring.http.encoding=enabled的情况下,如果没有设置则默认为true,即条件符合;
④像使用Java配置的方式配置CharacterEncodingFilter这个Bean;
⑤当容器中没有这个Bean的时候新建Bean。
实战
举个例子,包含当某个类存在的时候,自动配置这个类的Bean,并可将Bean的属性在application.properties中配置。
(1)新建starter的Maven项目,如图所示。
在pom.xml中修改代码如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wisely</groupId>
<artifactId>spring-boot-starter-hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-starter-hello</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>1.3.0.M1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<!-- 使用Spring Boot正式版时,无须下列配置 -->
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
代码解释
在此处增加Spring Boot自身的自动配置作为依赖。
(2)属性配置,代码如下:
package com.wisely.spring_boot_starter_hello;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "hello")
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;
}
}
代码解释
这里的配置是类型安全的属性获取。在application.properties中通过hello.msg=来设置,若不设置,默认为hello.msg=world。
(3)判断依据类,代码如下:
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;
}
}
代码解释
本例根据此类的存在与否来创建这个类的 Bean,这个类可以是第三方类库的类。
(4)自动配置类,代码如下:
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)
@ConditionalOnProperty(prefix = "hello", value = "enabled", matchIfMissing = true)
public class HelloServiceAutoConfiguration {
@Autowired
private HelloServiceProperties helloServiceProperties;
@Bean
@ConditionalOnMissingBean(HelloService.class)
public HelloService helloService() {
HelloService helloService = new HelloService();
helloService.setMsg(helloServiceProperties.getMsg());
return helloService;
}
}
代码解释
根据HelloServiceProperties提供的参数,并通过@ConditionalOnClass判断HelloService这个类在类路径中是否存在,且当容器中没有这个Bean的情况下自动配置这个Bean。
(5)注册配置。若想自动配置生效,需要注册自动配置类。在src/main/resources下新建META-INF/spring.factories,结构如图所示。
在spring.factories中填写如下内容注册:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.wisely.spring_boot_starter_hello.HelloServiceAutoConfiguration
若有多个自动配置,则用“,”隔开,此处“\”是为了换行后仍然能读到属性。
另外,若在此例新建的项目中无src/main/resources文件夹,右键单击项目名称,New->Source Folder,执行如图所示操作。
(6)使用starter。新建Spring Boot项目,并将我们的starter作为依赖,如图所示。
在pom.xml中添加spring-boot-starter-hello的依赖,代码如下:
<dependency>
<groupId>com.wisely</groupId>
<artifactId>spring-boot-starter-hello</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
我们可以在Maven的依赖里查看spring-boot-starter-hello,如图所示。
在开发阶段,我们引入的依赖是spring-boot-starter-hello这个项目,在starter稳定之后,我们可以将spring-boot-starter-hello通过“mvn install”安装到本地库,或者将这个jar包发布到Maven私服上。
简单的运行类代码如下:
package com.wisely.demospringboot;
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 DemoSpringbootApplication {
@Autowired
HelloService helloService;
@RequestMapping("/")
public String index() {
return helloService.sayHello();
}
public static void main(String[] args) {
SpringApplication.run(DemoSpringbootApplication.class, args);
}
}
在代码中可以直接注入HelloService的Bean,但在项目中我们并没有配置这个Bean,这是通过自动配置完成的。
访问http://localhost:8080/,效果如图所示:
这时,在application.properties中配置msg的内容:
此时再次访问http://localhost:8080,效果如图所示。
在application.properties中添加debug属性,查看自动配置报告:
我们新增的自动配置显示在控制台的报告中,如图所示。