SpringBoot從入門到放棄,第一章
一、簡單概述
先談一下什麼是Spring
Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》。Spring是爲了解決企業級應用開發的複雜性而創建的,使用Spring可以讓簡單的JavaBean實現之前只有EJB才能完成的事情。但是Spring不僅僅侷限於服務器端開發,任何Java應用都能在簡單性、可測試性和松耦合性等方面從Spring中獲益。
爲了降低Java開發的複雜性,Spring採用了以下4種關鍵策略:
1、基於POJO的輕量級和最小侵入性編程;
2、通過依賴注入(DI)和麪向接口實現松耦合;
3、基於切面(AOP)和慣例進行聲明式編程;
4、通過切面和模版減少樣式代碼;
什麼是SpringBoot
Spring Boot 是所有基於 Spring 開發的項目的起點。Spring Boot 的設計是爲了讓你儘可能快的跑起來 Spring 應用程序並且儘可能減少你的配置文件。簡單來說就是SpringBoot其實不是什麼新的框架,它默認配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架(不知道這樣比喻是否合適)。
SpringBoot的四大特性
1、SpringBoot Starter:他將常用的依賴分組進行了整合,將其合併到一個依賴中,這樣就可以一次性添加到項目的Maven或Gradle構建中;
2、自動配置:SpringBoot的自動配置特性利用了Spring4對條件化配置的支持,合理地推測應用所需的bean並自動化配置他們;
3、命令行接口:(Command-line-interface, CLI):SpringBoot的CLI發揮了Groovy編程語言的優勢,並結合自動配置進一步簡化Spring應用的開發;
4、Actuatir:它爲SpringBoot應用的所有特性構建一個小型的應用程序。但首先,我們快速瞭解每項特性,更好的體驗他們如何簡化Spring編程模型。
二、SpringBoot的場景啓動器
什麼是場景啓動器
Spring boot將所有的功能場景都抽取出來,做成一個個獨立的starters啓動器
只有在項目裏引入了starters,這些場景的依賴就會導入到工程中
開發中需要什麼樣的功能,就引入什麼場景啓動器
如果想使用Spring和JPA進行數據庫訪問,只需spring-boot-starter-data-jpa在項目中包含依賴項即可。
spring-boot-starter-parent
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
</parent>
這是Spring Boot的父級依賴,這樣當前的項目就是Spring Boot項目了。
spring-boot-starter-parent 是一個特殊的starter,它用來提供相關的Maven默認依賴。使用它之後,常用的包依賴可以省去version標籤。
先來看 parent 的基本功能有哪些?
1、定義了 Java 編譯版本爲 1.8 。
2、使用 UTF-8 格式編碼。
3、繼承自 spring-boot-dependencies,這個裏邊定義了依賴的版本,也正是因爲繼承了這個依賴,所以我們在寫依賴時纔不需要寫版本號。
4、執行打包操作的配置。
5、自動化的資源過濾。
6、自動化的插件配置。
7、針對 application.properties 和 application.yml 的資源過濾,包括通過 profile 定義的不同環境的配置文件,例如 application-dev.properties 和 application-dev.yml。
下面列舉一下常用的starter
spring-boot-starter-web
spring-boot-starter-thymeleaf
spring-boot-starter-test
spring-boot-starter-security
spring-boot-starter-jdbc
spring-boot-starter-freemarker
spring-boot-starter-data-redis
spring-boot-starter-data-solr
spring-boot-starter-data-jpa
spring-boot-starter-aop
spring-boot-starter-batch
spring-boot-starter-amqp
spring-boot-starter-activemq
。。。
三、SpringBoot的啓動類
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
}
@SpringBootApplication表示這是一個SpringBoot應用
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 {
...
}
1、@SpringBootConfiguration: Spring Boot的配置類
標註在某個類上,表示這是一個SpringBoot的配置類
其中**@Configuration**:配置類上來標註這個註解
配置類—配置文件:配置類也是容器中的一個組件,其底層是**@Component**
@Configuration
public @interface SpringBootConfiguration {
...
}
@Component
public @interface Configuration {
...
}
**2、@EnableAutoConfiguration:**開啓自動配置功能
以前需要配置的東西,Spring Boot幫助我們自動配置;@EnableAutoConfiguration告訴
SpringBoot開啓自動配置功能.
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
**2.1)、@AutoConfigurationPackage:**自動配置包
底層:@Import(AutoConfigurationPackages.Registrar.class)
spring的底層註解@Import,給容器中導入一個組件;
導入的組件由Registrar.class
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
//AnnotationMetadata掃描到的類上有註解的類
//PackageImport(metadata).getPackageName()獲取該類的包名
//register註冊
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
...
}
以上:將主配置類(@SpringBootApplication標註的類)的所在包及下面所有包裏面的所有組件註冊到Spring容器。
2.2)、@Import(AutoConfigurationImportSelector.class):
給容器注入組件:AutoConfigurationImportSelector
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
將所有需要導入的組件以全類名的方式返回;這些組件就會被添加到容器中
會給容器中導入非常多的自動配置類(xxxAutoConfiguration),這些配置類的左右是給容器中導入這個場景需要的所有的組件,並配置好這些組件
有了自動配置類,就免去了我們手動編寫配置和注入功能組件等工作。
從META-INF/spring.factories裏導入EnableAutoConfiguration場景所制定的配置類
四、YAML配置文件
4.1)、全局配置文件
SpringBoot使用一個全局的配置文件,配置文件名是固定的
application.properties
application.yml
配置文件放在src/main/resources目錄或者類路徑/config下
全局配置文件可以對一個springboot的默認配置值進行修改
4.2)、默認語法:
server:
port: 8080
key和value中間有空格,大小寫敏感
k:v 字符串默認不用加單引號或者雙引號;
“”:雙引號;不會轉義字符串裏面的特殊字符
name: “zhangsan \n lisi” 輸出:zhangsan 換行 lisi
‘’:單引號,會轉義特殊字符,只會將其當做一個普通的字符串輸出
name: “zhangsan \n lisi” 輸出:zhangsan \n lisi
對象表達;
friends:
lastname: zhangsan
age: 25
##或者
friends: {lastname: zhangsan,age: 25}
數組;(用- 值表示數組中的一個元素)
pets:
- cat
- dog
- rabbit
##或者
pets: [cat,dog,rabbit]
MAP;
maps: {k1: v1,k2: v2}
4.3)、yaml文件值獲取
@ConfigurationProperties告訴SpringBoot本類中所有屬性和配置文件中相關的配置進行綁定
且只有這個組件是容器中的組件,才能使用容器提供的@ConfigurationProperties功能
person:
name: lee
age: 28
map: {k1: v1,k2: v2}
pets:
- dog
- cat
- rabbit
實體類:
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Map<String,Object> map;
private List<String> pets;
}
同樣的配置在application.properties中怎樣配置呢:
person.name=lee
person.age=28
person.map.k1=v1
person.map.k2=v2
person.map.pets=dog,cat,rabbit
五、@ConfigurationProperties和@Value
@ConfigurationProperties是springboot中的註解
@Value是spring中的註解
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.beans.factory.annotation.Value;
@Data
@ToString
@Component
//@ConfigurationProperties(prefix = "person")
public class Person {
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
//map
@Value("#{${person.map}}")
private Map<String,String> map;
//list
@Value("#{'${person.pets}'.split(',')}")
private List<String> pets;
}
不過yml要寫成一下格式
person:
name: lee
age: 28
map: "{key1: 'value1', key2: 'value2'}"
pets: topic1,topic2,topic3
##不能寫成
person:
name: lee
age: 28
map: {k1: v1,k2: v2}
pets:
- dog
- cat
- rabbit
測試:
@RunWith(SpringRunner.class)
@org.springframework.boot.test.context.SpringBootTest
public class SpringBootTest {
@Autowired
private Person person;
@Test
public void contextLoader(){
System.out.println(person);
}
}
六、@PropertySource和@ImportResource
@ConfigurationProperties:是默認加載全局配置文件中的值
@PropertySource:加載指定的配置文件
@ImportResource:導入spring的配置文件,讓配置文件裏面的內容生效
6.1)、@PropertySource
加載指定的配置文件
pet.properties
pet.name=dog
pet.age=5
pet.color=yellow
Pet
@Data
@ToString
@Component
@PropertySource(value = {"classpath:pet.properties"})
public class Pet {
@Value("${pet.name}")
private String name;
@Value("${pet.age}")
private Integer age;
@Value("${pet.color}")
private String color;
}
6.2)、ImportResource
導入spring的配置文件,讓配置文件裏面的內容生效
beans.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="helloService" class="com.lee.boot.service.HelloService"></bean>
</beans>
HelloService
package com.lee.boot.service;
public class HelloService {
}
測試:
@RunWith(SpringRunner.class)
@org.springframework.boot.test.context.SpringBootTest
public class SpringBootTest {
@Autowired
private ApplicationContext context;
@Test
public void containBeans(){
boolean res = context.containsBean("helloService");
System.out.println(res);
}
}
結果:false
SpringBoot裏面沒有spring的配置文件,我們自己編寫的配置文件,也不能自動識別;想讓spring的配置文件生效,加載進來;就需要將**@ImportResource**標註在一個配置類上
@ImportResource(value = {"classpath:beans.xml"})
@SpringBootApplication
public class BootApplication {
public static void main(String[] args) {
SpringApplication.run(BootApplication.class, args);
}
}
//標註在啓動類上也是可以的,因爲啓動類本身也是一個配置類,其底層也
//註解了@Configuration
結果:true
其實springboot不推薦使用配置文件的方式添加組件,而是推薦使用全註解的方式。
//configuration指明當前類是一個配置類,就是來替代之前的
//spring配置文件
@Configuration
public class MyAppConfig {
//使用@Bean給容器添加組件
//將方法的返回值添加到容器中
//容器中這個組件默認的ID就是方法名
@Bean
public HelloService helloService(){
return new HelloService();
}
}