文章目录
SpringBoot自动配置
1. SpringBoot优缺点
前面我们已经对SpringBoot有了简单的了解与使用。SpringBoot对于开发者来说使用非常方便,那我们先整理一下优缺点。
总结优点如下:
1)使编码变简单:为基于Spring的开发提供更快的入门体验,轻松创建可以独立运行的Spring应用。
2)使配置变简单:直接推荐的基础POM文件—starter来简化Apache Maven配置,尽可能的根据项目依赖来自动配置的Spring框架。
3)使部署变简单:直接嵌入Tomcat或Jetty服务器,不需要再打包成WAR文件。
4)使监控变简单:提供可以直接在生产环境中使用的功能,如性能指标、应用信息和应用健康检查等。
总结缺点如下:
1)依赖太多,随便的一个SpringBoot应用都有好几十M。
2)缺少服务的注册和发现等解决方案。
3)缺少监控集成方案、安全管理方案。
4)中文的文档和资料少且不够深入。
基于SpringBoot的特点,主要应用场景如下:
1)Spring能够应用的场景。
2)Java Web应用。
3)微服务。
2. 快速入门回顾
2.1 创建项目
IDEA创建一个SpringBoot项目,项目结构如下:
我们发现,自动创建了一个类Application,我们称之为启动类。.mvn目录、mvnw与mvnw.cmd文件可以删掉;
2.2 环境搭建
我们用Idea创建SpringBoot web项目,自动为我们搭建好了环境。我们查看POM文件,发现搭建SpringBoot环境,是采用继承的方式:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
若想集成SpringBoot环境,还有第二种方式,即配置dependencyManagement,POM配置如下:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.8.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
2.3 启动项目
我们知道项目启动依靠的是启动器(启动类),这是创建项目时自动为我们创建的,只要运行其中的main方法,即启动项目。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
启动方式除了默认的调用SpringApplication的静态方法run之外,还可以通过SpringApplication实例调用run方法实现,代码如下:
@SpringBootApplication
public class App1 {
public static void main(String[] args) {
SpringApplication application = new SpringApplication();
application.run(App1.class, args);
}
}
@SpringBootApplication
public class App2 {
public static void main(String[] args) {
SpringApplication springApplication = new SpringApplication(App2.class);
springApplication.run(args);
}
}
2.4 初识@SpringBootApplication注解
@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 {
//...
}
我们发现该注解中包含了4个元注解与3个Spring注解:
1)4个元注解:
@Target:定义注解的作用目标 。
@Retention: 定义注解的保留策略 。
@Document:说明该注解将被包含在javadoc中。
@Inherited:说明子类可以继承父类中的该注解。
2)3个Spring的注解:
@ComponentScan:自动扫描包(扫描项目中标注为Spring组件的类,从而使标注controller、service、repository及component的bean都能正常注入到Spring容器并提供使用)。
@EnableAutoConfiguration:开启自动配置,后面作详细介绍。
@SpringBootConfiguration:标注当前类作为配置类,作为配置类后我们就可以在该类中配置Bean了。
@SpringBootConfiguration的作用,演示效果如下:在该类中配置一个bean,在项目启动中可以通过context对象获取到该实例,说明已经该bean成功被注入到Spring容器中了。
@SpringBootApplication
public class Application {
@Bean
public Runnable createRunnable() {
return () -> {
System.out.println("Creating runnable...");
};
}
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
context.getBean(Runnable.class).run();
context.close();
}
}
3. SpringBoot配置分析
3.1 获取配置文件中的值
3.1.1 直接获取配置文件中变量的值
在配置文件application.properties中添加配置信息:
local.ip=192.168.198.132
local.port=8023
local.name=chavaer
根据key获取配置文件中的值,有两种方式,如下:
1)通过Environment对象的getProperty()方法获取;
2)通过@Value注解获取;
代码实现:
package com.chavaer.springboot;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
@Component
public class Config {
@Autowired
private Environment env;
//方法3:通过@Value注解获取
@Value("${local.name}")
private String name;
//方法4:通过@Value注解获取,自动进行类型转换
@Value("${local.port}")
private Integer port;
public void getCfgValue() {
//方法1:通过getProperty()方法获取
String ip = env.getProperty("local.ip");
//方法2:通过getProperty()方法获取,自动进行类型转换
Integer localPort = env.getProperty("local.port", Integer.class);
System.out.println("local.ip:" + ip);
System.out.println("local.port:" + localPort);
System.out.println("local.name:" + name);
System.out.println("local.port:" + port);
}
}
@SpringBootApplication
public class App {
public static void main(String[] args) {
ConfigurableApplicationContext context =
SpringApplication.run(App.class, args);
context.getBean(Config.class).getCfgValue();
context.close();
}
}
控制台打印信息如下:
3.1.2 获取配置文件中引用变量的值
当配置文件中存在引用变量时,获取方式同上:
project=springboot
project.name=this is ${project}
@Component
public class Config {
@Autowired
private Environment env;
public void getCfgValue() {
String name = env.getProperty("project");
String proName = env.getProperty("project.name");
System.out.println("project:" + name);
System.out.println("project.name:" + proName);
}
}
获取结果如下:
3.1.3 获取配置文件中不存在的键值对
当给定Key在配置文件中不存在时,需要给定默认值,否则会报错。如我们获取Key为“tomcat.port”的值,我们并没有在配置文件中配置:
@Component
public class Config {
@Autowired
private Environment env;
@Value("${tomcat.port}")
private String tomcatPort;
public void getCfgValue() {
System.out.println("tomcat.port:" + tomcatPort);
}
}
出现异常信息如下:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'config': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'tomcat.port' in value "${tomcat.port}"
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:380) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.9.RELEASE.jar:5.1.9.RELEASE]
at org