SpringBoot從入門到放棄,第一章

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();
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章