SpringBoot2——基础入门
一、Spring 与 SpringBoot
1. SpringBoot优缺点
1.1 优点
- 创建独立Spring应用
- 内嵌web服务器
- 自动starter依赖,简化构建配置
- 自动配置Spring以及第三方功能
- 提供生产级别的监控、健康检查及外部化配置
- 无代码生成、无需编写XML
1.2 缺点
- 人称版本帝,迭代快,需要时刻关注变化
- 封装太深,内部原理复杂,不容易精通
2. 如何学习
官方参考文档:Spring Boot Reference Documentation
版本新特性:Home · spring-projects/spring-boot Wiki · GitHub
二、SpringBoot2快速入门
1. 环境要求
- Java 8 & 兼容 java14 .
- Maven 3.3+
- idea 2019.1.2
2. 创建Hello工程
2.1 工程文件
- pom.xml
<?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>net.tiejiankudan</groupId>
<artifactId>part01_quicklyStart</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 貌似不写也不影响打包 -->
<packaging>jar</packaging>
<!-- 父工程作了很多版本控制(点开他的父工程就可以看到了) -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.4.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- 打包必备 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- 主程序:net.tiejiankudan.MainApplication
// 组合注解,默认扫描当前类所在的包及其子包,也可以通过 scanBasePackages 改变扫描范围
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(MainApplication.class, args);
}
}
- controller:net.tiejiankudan.controller.HelloController
// 相当于 @ResponseBody + @Controller
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello, Spring Boot 2";
}
}
- 因为集成tomcat,所以修改配置文件就可以配置tomca了
- application.properties
2.2 测试
运行 net.tiejiankudan.MainApplication 即可。
2.3 简化部署
- 打成jar包,使用mvn: package,千万不要使用Plugins下jar打包,那个没用
- 运行jar包
java -jar 包路径
三、了解自动配置原理
1. SpringBoot特点
- 父项目做依赖版本管理
- spring-boot-starter-parent =》spring-boot-dependencies
- 想要改版本的话,找到spring-boot-dependencies里定义好的标签名,在自己的项目配置里重写即可
<properties> <mysql.version>5.1.43</mysql.version> </properties>
- starter场景启动器自动导入所需jar包还做好了自动配置
- spring-boot-starter-* 官方启动器
- *-spring-boot-starter 第三方启动器
- 启动器大全:Using Spring Boot
- 各种配置拥有默认值
-
- 默认配置最终都是映射到某个类上,如:MultipartProperties
- 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
- 按需加载所有自动配置项
-
- 引入了哪些场景这个场景的自动配置才会开启
- SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
2. 容器功能
2.1 组件添加
2.1.1 配置类
@Configuration
- 声明一个配置类,配置类也会加入到IOC容器
- Full模式与Lite模式
net.tiejiankudan.config.Myconfig
// Full(proxyBeanMethods = true)
// Lite(proxyBeanMethods = false)
@Configuration(proxyBeanMethods = true)
public class Myconfig {
@Bean
public User user() {
return new User();
}
}
net.tiejiankudan.MainApplication
public class MainApplication {
public static void main(String[] args) {
// 1.返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
// 2.查看容器中的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
// 3.从容器中获得组件:不管是Lite还是Full都是同一个
User user = run.getBean("user", User.class);
User user2 = run.getBean("user", User.class);
System.out.println("user1: " + user);
System.out.println("user2: " + user2);
// 通过配置组件创建对象: Lite不是同一个,Full是同一个
Myconfig config = run.getBean(Myconfig.class);
User user3 = config.user();
User user4 = config.user();
System.out.println(user3);
System.out.println(user4);
/************************************************************
* 结论:
* proxyBeanMethods = true 时,
* 调用创建Bean的方法时会检测容器中是否已经存在Bean了,
* 存在则直接用容器中的Bean
* proxyBeanMethods = false 时,
* 则不会检测,直接new出新的Bean,比true速度快,
* 故称之为Lite
************************************************************/
}
}
2.1.2 添加Bean
@Bean、@Component、@Controller、@Service、@Repository
2.1.3 组件扫描
@ComponentScan
2.1.4 导入配置
@Import({Object1.class, Object2.class}):
- 就是给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
2.1.5 条件装配
@Conditional:
- 满足Conditional指定的条件,则进行组件注入
net.tiejiankudan.config.Myconfig
@Configuration(proxyBeanMethods = true)
//@ConditionalOnBean(name = "tom")
@ConditionalOnMissingBean(name = "tom")
public class Myconfig {
}
net.tiejiankudan.MainApplication
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
Object tom = run.getBean("tom");
Myconfig myconfig = run.getBean(Myconfig.class);
System.out.println(tom);
System.out.println(myconfig);
/************************************************************
* 结论:
* @ConditionalOnBean(name = "tom")生效时:
* 容器中有叫tom的Bean时,Myconfig才被加入到容器中
* @ConditionalOnMissingBean(name = "tom")生效时:
* 容器中没有叫tom的Bean时,Myconfig才被加入到容器中
利用这个注解Spring-boot才能做到按需加载配置类进入容器
************************************************************/
}
}
2.2、原生配置文件引入
2.2.1 引入配置文件
@ImportResource:
- 引入SSM时期一直用的xml配置文件,不过一定要注意配置文件名不要命名成application.xml,这样会报错。
bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="tom" class="net.tiejiankudan.domain.User"></bean>
<bean id="jerry" class="net.tiejiankudan.domain.User"></bean>
</beans>
net.tiejiankudan.config.Myconfig
@Configuration(proxyBeanMethods = true)
@ImportResource("classpath:bean.xml")
public class Myconfig {
}
net.tiejiankudan.MainApplication
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
public static void main(String[] args) {
// 1.返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
Object tom = run.getBean("tom");
Object jerry = run.getBean("jerry");
System.out.println(tom);
System.out.println(jerry);
/************************************************************
* 结果:
* [email protected]
* [email protected]
************************************************************/
}
}
2.2.2 配置绑定
如何使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用。
声明成属性类后,会出现个提示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4NFHZQQ1-1622093046923)(D:\Document\Note\picture\002.jpg)]
不要让他出现的话可以添加依赖:
<dependency> <groupId> org.springframework.boot </groupId> <artifactId>spring-boot-configuration-processor</artifactId> <!--不传递依赖--> <optional>true</optional> </dependency>
方式一:@Component + @ConfigurationProperties(prefix = “xxx”)
net.tiejiankudan.property.CarProperties
// 加入到IOC容器中就可以自动配置属性了,代替了之前的@PropertySource() + @Value 的做法
@Component
@ConfigurationProperties(prefix = "mycar")
public class CarProperties {
private String brand;
private Integer price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}
application.properties
server.port=9000
mycar.brand=wulinghonguang
mycar.price=23333
net.tiejiankudan.MainApplication
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
public static void main(String[] args) {
// 1.返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
CarProperties carProperties = run.getBean(CarProperties.class);
System.out.println(carProperties);
/************************************************************
* 结果:
* Car{brand='wulinghonguang', price=23333}
************************************************************/
}
}
方式二:@EnableConfigurationProperties + @ConfigurationProperties(prefix = “xxx”)
net.tiejiankudan.property.CarProperties
// 注意 @Component 是被注释了的
// @Component
@ConfigurationProperties(prefix = "mycar")
public class CarProperties {
private String brand;
private Integer price;
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Integer getPrice() {
return price;
}
public void setPrice(Integer price) {
this.price = price;
}
@Override
public String toString() {
return "Car{" +
"brand='" + brand + '\'' +
", price=" + price +
'}';
}
}
net.tiejiankudan.config.Myconfig
@Configuration(proxyBeanMethods = true)
// 下面的注解又把配置类加入到容器中
@EnableConfigurationProperties(CarProperties.class)
public class Myconfig {
@Bean
public Car car(CarProperties carProperties) {
Car car = new Car();
car.setBrand(carProperties.getBrand());
car.setPrice(carProperties.getPrice());
return car;
}
}
net.tiejiankudan.MainApplication
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
public static void main(String[] args) {
// 1.返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
CarProperties carProperties = run.getBean(CarProperties.class);
Car car = run.getBean(Car.class);
System.out.println("carProperties: " + carProperties);
System.out.println("car" + car);
/************************************************************
* 结果:
* carProperties: Car{brand='wulinghonguang', price=23333}
* carCar{brand='wulinghonguang', price=23333}
************************************************************/
}
}
方式二: @ConfigurationProperties(prefix = “xxx”)
- 思考:属性类在容器中 =》容器自动注入属性
- 那么:任何对象,只要在容器中就可以自动注入属性,那还要什么属性类(●’◡’●)
net.tiejiankudan.config.Myconfig
@Configuration(proxyBeanMethods = true)
public class Myconfig {
@Bean
@ConfigurationProperties(prefix = "mycar")
public Car car() {
return new Car();
}
}
net.tiejiankudan.MainApplication
@SpringBootApplication(scanBasePackages = "net.tiejiankudan")
public class MainApplication {
public static void main(String[] args) {
// 1.返回IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
Car car = run.getBean(Car.class);
System.out.println("car" + car);
/************************************************************
* 结果:
* carCar{brand='wulinghonguang', price=23333}
************************************************************/
}
}
3. 自动配置原理
太复杂了,我暂时先跳过╮(╯-╰)╭
4. 开发小技巧
4.1 Lombok
简化JavaBean开发
- idea中搜索安装lombok插件
- 在pom文件中引入依赖
pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- 在类上标明注解:
- @NoArgsConstructor:自动加入无参构造
- @AllArgsConstructor:自动加入全参构造
- @Data:自动get/set方法
- @ToString:自动加入tostring()方法
- @EqualsAndHashCode:自动重写equals和HashCode方法
- @Slf4j:标注后该类里就有了一个静态属性log
4.2 dev-tools
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
项目或者页面修改以后:Ctrl+F9重新构建项目。参考:Spring DevTools
4.3 Spring Initializr
项目创建的时候直接创建spring-boot项目可加速构建项目