一.入口类
通常而言,Spring Boot都会拥有一个名为*Application的入口类(如FirstApplication),而该入口类中会有一个main方法。这个main方法起始就是一个标准的Java应用的入口方法。在main方法中使用SpringApplication.run(xxx.class,args)方法从而启动Spring Boot项目。
二.@Spring BootApplication注解
Spring BootApplication注解是Spring Boot的核心注解,它是一个组合注解。
@Spring BootApplication注解中就已经包含了@Configuration(@Spring BootConfiguration中),@ComponentScan及@EnableAutoConfiguration。如果不使用@Spring BootApplication注解,可以在入口类上添加@Configuration,@ComponentScan及@EnableAutoConfiguration三个注解。
其中,@EnableAutoConfiguration注解会开启自动配置,简单点说就是它会根据定义在classpath下的类,自动的给你生成一些Bean,并加载到Spring的Context中。如在上一篇文章中( Spring Boot学习(二)——入门)的入门案例中添加了spring-boot-starter-web的依赖,则会开启Spring MVC自动配置。通过观察观察启动日志,我们发现应用启动了tomcat和spring mvc。
三.Spring Boot的配置文件
1.默认属性
Spring Boot使用一个全局配置文件application.properties或者application.yml,该文件放置在src/main/resources目录下或者在类路径下的/config目录下。
1).使用application.properties
配置文件如下:
#设置tomcat的端口号
server.port=8088
#设置项目的路径,server.context-path也可以用server.contextPath代替
server.context-path=/demo
#设置servlet的拦截路径
server.servlet-path=*.html
输出日志如下:
此时访问项目的路径为localhost:8088/demo/xxx.html。其它配置可以参考SpringBoot官方的的参考文件
地址链接:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html
2).使用application.yml
yml文件格式如下
server:
port: 8088
context-path: /demo
my:
test: this is my property
注意:
1.以上属性相当于properties中配置了server.port、server.context-path、my.test三个属性,server相当于一级属性,port相当于二级属性,其中port前需要带有空格用于区分其是server的下级,如果不带空格则会认为port也是一级属性(即每一级属性要比上一级属性多一个空格缩进)
2.每一级属性要比上一级属性多一个缩进,而且只能用空格,不能用Tab键进行缩进,否则报错。
3.属性值前需要带空格,例如“port: 8088”,其中属性“port:”与属性值“8088”之间有个空格
2.自定义属性
我们也可以在application.properties文件下自定义属性,如下:
my.test=this is my property
controller类
//引入属性
@Value("${my.test}")
public String test;
@RequestMapping("/properties")
@ResponseBody
public String testProperties(){
return test;
}
访问“;localhost:8080/properties”,此时页面输出“this is my property”
3.多属性自动引入
当配置文件中有多个属性时,可以通过@ConfigurationProperties注解引入,如果属性名前缀(如myProperties.name),可以在@ConfigurationProperties注解中添加prefix属性(如@ConfigurationProperties(prefix = “myProperties”))来指定前缀。
注意:该方式是以字段的setter方法注入,所以不能省略字段的setter方法。
如果需要指定配置文件,可以使用@PropertySource注解指定文件路径(如@PropertySource(“classpath:config/myProperties.properties”))
配置文件如(路径为classpath:config/myProperties.properties):
myproperties.name=zs
myproperties.age=23
测试类
@Controller
@ConfigurationProperties(prefix = "myproperties")
@PropertySource("classpath:config/myProperties.properties")
public class HelloSpringBoot {
private String name;
private String age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
@RequestMapping("/myproperties")
@ResponseBody
public void testMyProperties(){
System.out.println("name="+name+",age="+age);
}
}
访问路径“localhost:8080/myproperties”,此时控制台输出“name=zs,age=23”
四.自定义banner
在项目启动时打印的banner可以通过在类路径添加一个banner.txt文件,或者通过在配置文件(application.properties)中设置banner.location属性到此类文件的位置来更改。如果文件有一个不常用的编码,可以设置banner.charset属性(默认是UTF-8)。除了文本文件,还可以将banner.gif,banner.jpg或banner.png图像文件添加到您的类路径中,或者设置banner.image.location属性。图像将被转换成ASCII艺术表现,并打印在任何文字横幅上方。
可以通过http://patorjk.com/software/taag网站生成字符,直接将生成的字符复制到banner.txt文件中即可。
提供一个字符画生成网站http://y.qq.com/m/demo/ctools/charimg.html
_ooOoo_
o8888888o
88" . "88
(| ^_^ |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . ___
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
========`-.____`-.___\_____/___.-`____.-'========
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
*************佛祖保佑*************
*************永不宕机*************
*************永无BUG*************
如果不需要banner,可以按以下方式启动
SpringApplication application = new SpringApplication(FirstApplication.class);
//Mode.CONSOLE表示输出至控制台
//Mode.LOG表示输出至日志
//Mode.OFF表示不输出banner
application.setBannerMode(Mode.OFF);
application.run(args);
五.Starter配置
Starter是一组方便的依赖关系描述符,可以包含在应用程序中。 您可以获得所需的所有Spring和相关技术的一站式服务,而无需通过示例代码搜索和复制粘贴相关性描述符的配置。 例如,如果要开始使用Spring和JPA进行数据库访问,那么只需在项目中包含spring-boot-starter-data-jpa依赖项,然后你就可以开始使用。
Starter包含许多您需要使项目快速启动并运行的依赖关系,并支持依赖maven的管理依赖传递。
官方提供的Stater参考https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#using-boot-starter
六.加载的配置
Spring Boot支持基于Java的配置。虽然可以使用XML源调用SpringApplication.run(),但我们通常建议您的主源是一个@Configuration类。通常,定义main方法的类也是一个很好的候选者,作为主要的@Configuration。
许多Spring配置示例已经在Internet上发布,使用XML配置。始终尝试使用等效的基于Java的配置,如果可能的话。搜索启用*注释可以是一个很好的起点。
1.导入其他配置类
我们不需要将所有的@Configuration放在一个类中。 @Import注释可用于导入其他配置类。或者可以使用@ComponentScan自动扫描所有Spring组件,包括@Configuration类。
2.导入XML配置
官方推荐使用Java类的配置,但是如果我们绝对必须使用基于XML的配置,可以在入口类中使用额外的@ImportResource注释来加载XML配置文件。
@ImportResource({“classpath:some.xml”,”classpath:other.xml”})
七.自动配置原理
1.如何自动加载配置
是否自动加载类是根据@EnableAutoConfiguration注解中@Import(EnableAutoConfigurationImportSelector.class)进行判断。
查看SpringApplication的静态run方法会创建一个SpringApplication对象,而构造方法会调用initialize方法,initialize方法如下:
查看spring-boot-autoconfigure-1.5.2.RELEASE.jar的META-INF/spring.factories文件,里面配置了自动配置类的全路径,如下(此处只截取了部分):
2.配置注解
查看任意一个Auto Configure文件,一般都有下面的条件注解,在spring-boot-autoconfigure-1.5.2.RELEASE.jar的org.springframework.boot.autoconfigure.condition包下,条件注解如下:
条件注解 |
对应的Condition处理类 |
处理逻辑 |
@ConditionalOnBean |
OnBeanCondition |
Spring容器中是否存在对应的实例。可以通过实例的类型、类名、注解、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)这些属性都是数组,通过”与”的关系进行查找 |
@ConditionalOnClass |
OnClassCondition |
类加载器中是否存在对应的类。可以通过Class指定(value属性)或者Class的全名指定(name属性)。如果是多个类或者多个类名的话,关系是”与”关系,也就是说这些类或者类名都必须同时在类加载器中存在 |
@ConditionalOnExpression |
OnExpressionCondition |
判断SpEL 表达式是否成立 |
@ConditionalOnJava |
OnJavaCondition |
指定Java版本是否符合要求。内部有2个属性value和range。value表示一个枚举的Java版本,range表示比这个老或者新于等于指定的Java版本(默认是新于等于)。内部会基于某些jdk版本特有的类去类加载器中查询,比如如果是jdk9,类加载器中需要存在java.security.cert.URICertStoreParameters;如果是jdk8,类加载器中需要存在java.util.function.Function;如果是jdk7,类加载器中需要存在java.nio.file.Files;如果是jdk6,类加载器中需要存在java.util.ServiceLoader |
@ConditionalOnMissingBean |
OnBeanCondition |
Spring容器中是否缺少对应的实例。可以通过实例的类型、类名、注解、昵称去容器中查找(可以配置从当前容器中查找或者父容器中查找或者两者一起查找)这些属性都是数组,通过”与”的关系进行查找。还多了2个属性ignored(类名)和ignoredType(类名),匹配的过程中会忽略这些bean |
@ConditionalOnMissingClass |
OnClassCondition |
跟ConditionalOnClass的处理逻辑一样,只是条件相反,在类加载器中不存在对应的类 |
@ConditionalOnNotWebApplication |
OnWebApplicationCondition |
应用程序是否是非Web程序,没有提供属性,只是一个标识。会从判断Web程序特有的类是否存在,环境是否是Servlet环境,容器是否是Web容器等 |
@ConditionalOnProperty |
OnPropertyCondition |
应用环境中的屬性是否存在。提供prefix、name、havingValue以及matchIfMissing属性。prefix表示属性名的前缀,name是属性名,havingValue是具体的属性值,matchIfMissing是个boolean值,如果属性不存在,这个matchIfMissing为true的话,会继续验证下去,否则属性不存在的话直接就相当于匹配不成功 |
@ConditionalOnResource |
OnResourceCondition |
是否存在指定的资源文件。只有一个属性resources,是个String数组。会从类加载器中去查询对应的资源文件是否存在 |
@ConditionalOnSingleCandidate |
OnBeanCondition |
Spring容器中是否存在且只存在一个对应的实例。只有3个属性value、type、search。跟ConditionalOnBean中的这3种属性值意义一样 |
@ConditionalOnWebApplication |
OnWebApplicationCondition |
应用程序是否是Web程序,没有提供属性,只是一个标识。会从判断Web程序特有的类是否存在,环境是否是Servlet环境,容器是否是Web容器等 |