基本配置
@SpringBootApplication包含这三个注解:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan
@EnableAutoConfiguration:让spring boot根据当前项目的jar包依赖为当前项目自动配置
例如添加了spring-boot-starter-web的依赖,那么就会自动添加tomcat和spring mvc的依赖
springboot会自动扫描同级以及同级包下面的bean对象,建议入口类的放置位置在groupid和artifcatid组合包下面。
如果不需要扫描的包可以通过exclude排除掉。
定制banner
在src/main/resource 下面放置一个spanner.txt,然后去http://patorjk.com/software/taag/ 把生成banner,将生成的文字copy到banner.txt就可以修改spring boot启动的banner了
如果不喜欢启动的时候显示banner,也可以将启动的banner关闭,通过类似下面形式启动
SpringApplication app = new SpringApplication(DemoApplication.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
starter pom
spring boot 为我们提供了绝大多数的starter pom,只要使用了starter pom 相关的技术配置就会消除,就可以得到spring boot为我们提供的自动配置bean
spring boot 官方荐的starter pom 以及第三方的 pom配置参考
https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#using-boot-starter
使用xml
如果项目中实在要用到xml,则可以通过类似下面的方式引入
@ImportResource("classpath:context.xml")
常规属性配置
如果要用到properties里面的配置则可以通过配置注解@ImportRource 应用properties文件,然后通过@Value注解直接在代码里面使用properties里面的值
如果是application.properties里面的值的话,那么可以不需要配置@ImportRource注解,直接使用@Value注解引用properties里面的值就可以了
类型安全的配置
我们可以通过@ConfigurationProperties 注解和一个bean 对象绑定,直接将properties里面的对象绑定到bean里面
例如 application.properties里买定义内容
author.age=12
author.name=wahaha
然后在类里面直接定义bean生成对象,对象里面的值就包含properties里面的值
@ConfigurationProperties(prefix="author")
@Data
@Component
public class Author {
private String name;
private Integer age;
}
这样,获取到的bean author对象的属性就有值了。
spring boot的自动装备功能是通过spring-boot-autoconfigure实现的。
通过在application.properties里面设置下面的属性,就可以看到哪些组建被启动了,哪些没有被启动
debug=true
spring boot运行原理
如果我们在pom文件加入了对应的starter,那么spring就有了对应的功能,这个是怎么实现的呢?例如,我们在pom文件中加入了spring-boot-starter-web ,系统就自动识别除了,这个是一个web项目,这个是怎么实现的,下面我们以spring-boot-starter-web 来看看原理
当我们启用@SpringBootApplication注解,那么就会启用@EnableAutoConfiguration注解,@EnableAutoConfiguration注解里面倒入了这个类:AutoConfigurationImportSelector
这个类里面会通过SpringFactoriesLoader.loadFactoryNames方法去扫描META-INF/spring.factories的jar包(这个文件里面声明了有哪些自动配置)
那么如何判断项目需要启动web组建作为web项目呢
-
确认org.springframework.web.context.support.GenericWebApplicationContext是否在类路径里面
-
容器里面是否有session的scope
-
当前容器的environment是否有StandardServletEnvironment
-
当前的ResourceLoader是否为WebApplicationContext(ResourceLoader是 - ApplicationContext的顶级接口之一)
-
我们需要构造ConditionOutcome类的对象来帮助我们,最终通过ConditionOutcome.isMatch方法返回的布尔值来确定条件。
编写自己的starter pom
项目结构
pom文件配置
<?xml version="1.0" encoding="UTF-8"?>
<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.alipay</groupId>
<artifactId>spring-boot-starter-hello</artifactId>
<version>1.0-SNAPSHOT</version>
<name>spring-boot-starter-hello</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<!-- 需要spring boot 自身自动配置作为依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test-autoconfigure</artifactId>
<version>2.1.5.RELEASE</version>
</dependency>
</dependencies>
</project>
属性配置
package com.alipay;
/**
* 此类作为判断依据类,如果这个类存在那么就可以启动这个starter
* @author bijia
* @version $Id: HelloService.java, v 0.1 2019年06月01日 11:47 PM bijia Exp $
*/
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.alipay;
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;
/**
* 自动配置类
* @author bijia
* @version $Id: HelloAutoConfiguration.java, v 0.1 2019年06月01日 11:47 PM bijia Exp $
*/
@Configuration //标识此类为一个spring配置类
@EnableConfigurationProperties(value = HelloServiceProperteis.class) //启动配置文件,value用来指定我们要启用的配置类,可以有多个,多个时我们可以这么写value={xxProperties1.class,xxProperteis2.class....}
@ConditionalOnClass(HelloService.class) //表示当classPath下存在HelloService.class文件时改配置文件类才有效
@ConditionalOnProperty(prefix = "hello", value = "enable", matchIfMissing = true) //表示只有我们的配置文件是否配置了以hello为前缀的资源项值,并且在该资源项值为enable,如果没有配置我们默认设置为enable
public class HelloAutoConfiguration {
@Autowired
private HelloServiceProperteis helloServiceProperteis;
// 下面的意思是当容器没有这个bean 的时候,会新建这个bean
@Bean
@ConditionalOnMissingBean(HelloService.class)
public HelloService helloService() {
HelloService helloService = new HelloService();
helloService.setMsg(helloServiceProperteis.getMsg());
return helloService;
}
}
注册配置
在resources 的META-INF下面新增spring.factories文件,然后配置下面内容
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.alipay.HelloAutoConfiguration
以上spring-boot-starter-hello下载地址:https://download.csdn.net/download/fighterandknight/11221600
新加maven测试starter
新建一个spring boot web project,然后引入上面建立的jar,并在application.properties里面设置hello.msg的值
debug=true
hello.msg=bijia.whx
然后编写下面代码
import com.alipay.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class DemoApplication {
@Autowired
private HelloService helloService;
@RequestMapping("/")
public String index() {
return helloService.sayHello();
}
public static void main(String[] args) {
ConfigurableApplicationContext context=SpringApplication.run(DemoApplication.class, args);
}
}