此文為Spring Framework 5.1.5版本Core部分的用戶手冊的學習。對部分內容進行了翻譯摘取和學習理解,為了方便自己的在使用中具體細節處的回顧,建議配合原用戶手冊一起觀看。用戶手冊的地址為
https://docs.spring.io/spring/docs/5.1.5.RELEASE/spring-framework-reference/
目 錄
1 IOC容器... 3
1.1 簡介IOC容器和Beans. 3
1.2 容器概覽... 3
1.2.1 配置信息... 3
1.2.2 初始化一個容器... 3
1.3 Bean概覽... 4
1.3.1 Bean命名... 5
1.3.2 實例化Bean. 5
1.4 依賴... 7
1.4.1 依賴注入... 7
1.4.2 依賴配置的一些補充... 9
1.4.3 使用depends-on屬性... 15
1.4.4 延遲初始化Bean. 15
1.4.5 Xml中Bean標簽中的自動裝配... 16
1.4.6 Method Injection 方法注入##. 17
1.5 Bean的作用域... 17
1.5.5 自定義Bean的作用域... 18
1.6 定制Bean的特性... 18
1.6.1 生命周期回調... 18
1.6.2 ApplicationContextAware and BeanNameAware. 19
1.6.3 其他Aware. 20
1.7 Bean的繼承關系... 21
1.8 容器Container擴展的關鍵點... 21
1.8.1 BeanPostProcessor 21
1.8.2 BeanFactoryPostProcessor 21
1.8.3 FactoryBean. 21
1.9 基於注解的容器配置... 21
1.9.1 @Required. 22
1.9.2 @Autowired. 22
1.9.3 @Primary. 24
1.9.4 @Qualifier 24
1.9.5 可以自動注入到泛型類中... 27
1.9.6 CustomAutowireConfigurer 27
1.9.7 使用@Resource實現注入... 27
1.9.8 @PostConstruct @PreDestroy. 27
1.10 路徑掃描和注解管理... 27
1.10.4 使用@ComponentScan過濾要掃描的注解... 27
1.10.6 對自動注入的Bean實現命名... 28
1.10.7 給自動注入的Bean實現提供作用域... 29
1.10.9 生成一個候選Component的坐標... 30
1.11 使用JSR330標准的注解... 30
1.11.1 @Inject @Named. 31
1.11.2 @ManagedBean. 31
1.11.3 JSR330注解的一些限制... 31
1.12 通過Java代碼實現容器的配置... 32
1.12.2 AnnotationConfigApplicationContext 32
1.12.3 @Bean的一些相關... 33
1.12.5 Composing Java-based Configurations. 34
1.13 環境抽象... 35
1.13.1 Bean Definition Profiles. 35
1.13.2 PropertySource. 37
1.13.3 Using @PropertySource. 37
1.14 Registering a LoadTimeWeaver 37
1.15 ApplicationContext容器的一些額外功能... 38
1.16 BeanFactory. 38
2 Resources. 38
3 驗證、參數綁定、類型轉換... 39
3.1 驗證器... 39
3.3 BeanWrapper 39
3.3.1 settings and gettings. 39
3.3.2 PropertyEditor 40
3.4 Spring Type Conversion. 41
3.4.1 Converter接口... 41
3.4.2 ConverterFactory. 42
3.4.3 GenericConverter 42
3.4.4-3.46 ConversionService. 42
3.5 Spring Field Formatting. 43
3.5.1 Formatter格式器... 43
3.5.2 Annotation-driven Formatting. 43
3.5.3 FormatterRegistry格式器注冊... 45
3.5.4 FormatterRegistrar格式器注冊... 45
3.6 Configuring a Global Date and Time Format 45
3.7 Spring Validation. 46
3.7.1 JSR-303 Bean Validation API. 46
3.7.2 Configuring a Bean Validation Provider 46
3.7.3 Configuring a DataBinder 48
4 Spring Expression Language (SpEL) 48
5 AOP. 49
5.4 @AspectJ support 49
5.4.1. Enabling @AspectJ Support 49
5.4.2. Declaring an Aspect聲明切面... 49
5.4.3. Declaring a Pointcut 聲明切點... 50
5.4.4. Declaring Advice聲明通知... 52
5.4.5 Introductions-@DeclareParents. 52
1 IOC容器
1.1 簡介IOC容器和Beans
1.2 容器概覽
單機模式最常見的ClassPathXmlApplicationContext
or FileSystemXmlApplicationContext
1.2.1 配置信息
除了xml之外,還有兩種方式,第一種是在xml文件里添加<context:annotation-config/>,開啟自動配置;第二種是通過一些注解。
1.2.2 初始化一個容器
可以一次讀取多個xml。
還可以在xml文件的beans標簽內通過import引入其他xml文件。
1.3 Bean概覽
Bean在容器中存儲是以BeanDefinition的形式存在的。
下邊的是Bean的一些屬性
然后還可以調用getBeanFactory方法之后獲得一個BeanFactory對象,然后再注冊不在容器中的Bean。
1.3.1 Bean命名
Bean里邊的id屬性和name屬性是不同的。
Id傳唯一id,name可以傳別名,可用通過逗號和分號分隔好多別名
Xml里邊還可以傳入alias標簽,提供額外的別名。這樣就可以通過后邊的別名訪問Bean
1.3.2 實例化Bean
通過class指定要生成什么類,還可以通過以下兩種方法生成,后邊會有。
如果想要一個內部類的話,那么要使用二進制方法。下邊加了個$號
通過靜態工廠方法實例化Bean
這個例子不太好,其實應該是一個工廠類里邊生成一個實例,ServiceFactory里邊生成一個service比較好。注意,這個里邊的class並不是返回對象的類型,這個xml中甚至都沒有返回的類型。
通過實例工廠實例化Bean,工廠需要實例,所以先創建一個工廠,然后Bean再跟工廠建立聯系。當然一個工廠里邊可以產出好多不同的對象,這里就不在截圖了。
1.4 依賴
1.4.1 依賴注入
通過構造器方法實現依賴注入,下邊那種index起始值是0.
注解@ConstructorProperties可以標注在構造器方法上
選擇構造器注入還是setter注入呢?強制的參數用構造器,可選的參數用setter。
依賴解析的過程
使用構造器注入可能會有循環依賴的問題。那么就改造下,用setter注入吧。
靜態工廠中也可以通過構造器注入的方式生成Bean,看下邊的。
1.4.2 依賴配置的一些補充
可以使用namespace。
可以在Bean中按下邊的方式傳入Properties對象。
可以使用idref標簽防錯,防止出現下邊的情況,把引用類型和值類型搞錯了。並保證引用的值一定存在。
在ref中使用parent屬性可以指定父容器中的值。
Inner Beans
Collections,參數中涉及集合類型
Collection Merging
空值和null值,如果是字符串類型的話,在xml里邊“”代表空字符串,要用null標簽表明是null值。
XML Shortcut with the p-namespace
這里大概講了下命名空間的使用。
XML Shortcut with the c-namespace
復合屬性名稱,如下邊的fred屬性有bob屬性,bob屬性有sammy屬性,最終給sammy賦值,要保證路徑上的屬性都不為空。
1.4.3 使用depends-on屬性
Bean之間有依賴關系,就是讓一些要被注入到別的Bean的Bean,作為屬性的Bean要提前完成實例化。
1.4.4 延遲初始化Bean
如果Bean被設置為延遲初始化的話,但是另一個非延遲的Bean依賴了它,那么他還是會在容器建好的時候被初始化。
1.4.5 Xml中Bean標簽中的自動裝配
這里講的是在xml中也可以對於當個Bean設置自動配置,比如一個A Bean依賴B Bean,那么B Bean配置好之后 ,在A Bean里邊可以不用ref指定BBean,在A的標簽中通過添加autowire屬性來設置自動裝配,根據不同的裝配規則,會把B自動注入到A中。
但是自動裝配有一些缺點和限制。不精確,容易有歧義,不能裝配基礎類型,然后會被精確地依賴注入所覆蓋。
將一個Bean排除在自動裝配之外,可以對Bean標簽中設置autowire-candidate屬性為false。
default-autowire-candidates標簽可以指定自動裝配哪些Bean,在Beans標簽中設置,通過模式匹配。比如有A依賴B,我們將autowire屬性設置為byType,在xml中2個B,這樣在idea里邊xml會被紅波浪線警告,因為A無法判斷應該加載哪個,我們在最頂層的Beans標簽中通過模式匹配的方式將default-autowire-candidates的值設置為能匹配上某一個標簽,那么最后所對應的B Bean就會被注入到A中。
1.4.6 Method Injection 方法注入##
看官方文檔沒看懂,網上搜了下,這個就是可以將抽象方法通過方法注入的方式變得可以使用。見下邊的兩個網址好了。Look-up method 和replace-method。還有@Lookup注解。
https://www.cnblogs.com/ViviChan/p/4981619.html
https://www.cnblogs.com/atwanli/articles/6154920.html
1.5 Bean的作用域
這里關於web那塊的說明可以到時候結合用戶手冊再看看。
關於把一個短生命周期的Bean注入到一個長聲明周期的Bean中,可以在Bean中添加<aop:scoped-proxy/>。原因可以見下邊的博文。
https://blog.csdn.net/soonfly/article/details/69360680
1.5.5 自定義Bean的作用域
1.6 定制Bean的特性
這里就是定義容器Container和Bean在整個生命周期里邊干什么,通過實現不同的接口來實現每一個環節的處理。
1.6.1 生命周期回調
這里先是將可以在Bean中的屬性設置init-method 和destroy-method標簽,沒什么好主意的。有一點,可以在Beans屬性中配置default-init-method,來自動識別每個Bean里邊的init,這樣省去了每個Bean中都單獨設置init的麻煩。default-destroy-method同理。
這里講了目前可以通過三種方式控制Bean的生成和摧毀,他們有着這樣的順序。
1.6.2 ApplicationContextAware and BeanNameAware
ApplicationContextAware接口實現后可以在創建Bean的同時,讓Bean獲得容器的控制權。
BeanNameAware的作用是讓Bean直到自己再容器中的名字。
1.6.3 其他Aware
1.7 Bean的繼承關系
1.8 容器Container擴展的關鍵點
1.8.1 BeanPostProcessor
1.8.2 BeanFactoryPostProcessor
1.8.3 FactoryBean
1.9 基於注解的容器配置
在xml文件中可以通過如下方式開啟注解掃描。
1.9.1 @Required
該注解用在setter方法上,是要求該屬性在配置Bean的信息時必須被注入。
1.9.2 @Autowired
在JSR 330規范中可以使用@Inject代替本注解
該注解可以在構造器方法、setter方法、屬性上。
還可以把同樣的很多Bean放到數組里或者其他集合里。
甚至在Map容器可以。
可以使用@Order和@Priority來控制容器中Bean的順序
默認情況下自動注入如果沒有可以注入的話會報錯,所以我們可以用@Autowired(required = false)實現非強制性的注入,這樣沒有Bean就不會報錯了。
采用Java8提供的Optional特性和Spring5中提供的@Nullable注解(可為空)來表達依賴注入的非必要性。
@Autowired注解還可以標注在Spring的容器屬性上。
1.9.3 @Primary
同一種類型的Bean,標注了這個那么優先用。
1.9.4 @Qualifier
該注解可以讓自動裝配的注解有一定優先級,或者做相關的模式匹配。
然后生成Bean的時候可以指定qualifier的value。
@Qualifier注解還可以被開發者組合或繼承實現新的注解。
1.9.5 可以自動注入到泛型類中
1.9.6 CustomAutowireConfigurer
1.9.7 使用@Resource實現注入
可以標注在屬性或setter方法上。
1.9.8 @PostConstruct @PreDestroy
@Resource和@PostConstruct @PreDestroy本身屬於java的,但在高版本jdk中就不是了,所以使用要注意。
1.10 路徑掃描和注解管理
@Component @Service @Controller @Repository @SessionScope
1.10.4 使用@ComponentScan過濾要掃描的注解
1.10.6 對自動注入的Bean實現命名
下邊的例子是可以在那些注解里邊添加名稱,如果沒有添加名稱的話那么就是類首字母小寫形式的命名。
可以實現BeanNameGenerator接口來實現自動裝配Bean的命名規則
1.10.7 給自動注入的Bean實現提供作用域
@Scope注解可以表明Bean的作用域
可以通過實現ScopeMetadataResolver接口實現@Scope配置的解析生成一個ScopeMetadata對象。
還有底下的,同1.5.4節講的內容
1.10.9 生成一個候選Component的坐標
雖然類路徑掃描速度非常快,但可以通過在編譯時創建候選的靜態列表來提高大型應用程序的啟動性能。在此模式下,所有作為組件掃描目標的模塊都必須使用此機制。
1.11 使用JSR330標准的注解
需要導入額外的模塊。
1.11.1 @Inject @Named
1.11.2 @ManagedBean
1.11.3 JSR330注解的一些限制
1.12 通過Java代碼實現容器的配置
1.12.2 AnnotationConfigApplicationContext
通過一個注解配置類傳入applicationcontext中,還可以把標注Configuration的類也穿進去。
1.12.3 @Bean的一些相關
@Bean可以傳入別名,也可以添加@Description描述
1.12.5 Composing Java-based Configurations
使用@Import注解可以導入別的配置類
@Configuration注解可以配合@ImportResource注解使用。
1.13 環境抽象
1.13.1 Bean Definition Profiles
使用@Profile注解表明環境
然后可以組合注解
然后通過xml的方式實現上邊不同環境一樣的效果
激活一種環境Activating a Profile。
1.13.2 PropertySource
1.13.3 Using @PropertySource
1.14 Registering a LoadTimeWeaver
@EnableLoadTimeWeaving
1.15 ApplicationContext容器的一些額外功能
1.16 BeanFactory
2 Resources
嗯。。講了一些怎么用ctx讀取資源,沒什么覺得特別重要的。
3 驗證、參數綁定、類型轉換
3.1 驗證器
Spring提供了一個Validator接口。
它提供了兩個方法,supports方法用於驗證是不是對應的類,validate方法用於提供驗證邏輯,並且可以把錯誤交給Error處理。
這里還提供了一個ValidationUtils類幫助我們做很多的驗證處理。
3.3 BeanWrapper
3.3.1 settings and gettings
The way the BeanWrapper works is partly indicated by its name: it wraps a bean to perform actions on that bean, such as setting and retrieving properties.
原文中說BeanWrapper的作用如其名,包裹一個javaBean然后在其上實施操作。
下邊是一個其的用例,使用它完成綁定。
3.3.2 PropertyEditor
Spring提供了很多能見類和string進行對應轉換的PropertyEditor類。
舉了兩個例子:
ClassEditor:在spring中幫助我們將xml中的string找到對應的class。
還有在springmvc中很多的PropertyEditor將http請求轉換成mvc中對應的類。
Spring中通過java.beans.PropertyEditorManager可以實現一定程度的自動注冊,但是具體的類名和文件結構要按照下邊的格式。
這一章節還講了幾種實現Editor和其注冊的方法。
3.4 Spring Type Conversion
實現類型轉換
3.4.1 Converter接口
3.4.2 ConverterFactory
3.4.3 GenericConverter
ConditionalGenericConverter接口用來實現條件converter
3.4.4-3.46 ConversionService
ConversionService的相關實現類可以起到一定的注冊converter的作用。
對於要轉換一些復雜類型,比如list中是Integer的到list中是String的,通過使用TypeDescriptor。
3.5 Spring Field Formatting
3.5.1 Formatter格式器
3.5.2 Annotation-driven Formatting
AnnotationFormatterFactory通過實現這個類去實現和Formatter進行相關綁定。
可以學習AnnotationFormatterFactory類,學習他如何與@NumberFormat這個注解進行綁定的。
3.5.3 FormatterRegistry格式器注冊
3.5.4 FormatterRegistrar格式器注冊
3.6 Configuring a Global Date and Time Format
3.7 Spring Validation
3.7.1 JSR-303 Bean Validation API
3.7.2 Configuring a Bean Validation Provider
LocalValidatorFactoryBean使用這個類,選擇某一種規格的Validator。
Injecting a Validator
這里的意思應該是指定不同的Validator。
Configuring Custom Constraints
要實現Validation,要兩步:1、@Constraint包含的注解。2、javax.validation.ConstraintValidator實現這個類
Spring-driven Method Validation
3.7.3 Configuring a DataBinder
4 Spring Expression Language (SpEL)
這一章節就是講SpEL的,大概內容就是比如xml或者注解中那些用#{}表示的內容。
關鍵的類就是ExpressionParser及其衍生類
5 AOP
5.4 @AspectJ support
5.4.1. Enabling @AspectJ Support
通過兩種開始開啟aop。
5.4.2. Declaring an Aspect聲明切面
5.4.3. Declaring a Pointcut 聲明切點
作為切點的方法必須是void類型的
切點里邊聲明的關鍵字有以下這些。
Combining Pointcut Expressions
這里有幾個簡單的切點的例子。
Examples
這一小節有很多的例子,可以看看如何使用。
Writing Good Pointcuts
5.4.4. Declaring Advice聲明通知
5.4.5 Introductions-@DeclareParents
這里主要講了@DeclareParents這個注解,能在不改動原類代碼的情況下額外添加方法,其實是通過實現另一個接口來實現的。
這里最重要的就是用mvn導入spring-aop的時候,它包含的aspectj是不全的,要使用@DeclareParents類,需要aspectj框架的jrt,tools和weaver,aop只包含了最后一個。很多教材都沒說這一點,在網上看了看估計是spring版本的問題,老的版本估計aop把包都包含了,反正在現在5.1.5的版本要自己額外引入。
5.4.6. Aspect Instantiation Models
可以指定切面的實例化方式,perthis和pertarget
5.5. Schema-based AOP Support 基於xml的AOP
5.6 Choosing which AOP Declaration Style to Use
選擇spring-aop還是aspectj的問題。
選擇xml風格還是@Aspect注解實現aop的問題。
5.8. Proxying Mechanisms
這里介紹了何時使用jdk動態代理和cglib。可以通過如下設置強制設置使用cglib
5.8.1 Understanding AOP Proxies
大概講了一堆,看了一下貌似是說自調用是不會觸發aop的。(就是比如要切的類含有兩個方法,一個方法里邊調用了另一個,這樣是不會觸發aop的)。
5.9. Programmatic Creation of @AspectJ Proxies用程序設置aop
可以看到下邊的是使用AspectJProxyFactory工廠,傳入目標類、(多個)切面,最終獲取到代理對象后在執行。
5.10. Using AspectJ with Spring Applications直接使用aspectj框架
在本節中,我們將介紹如何使用AspectJ編譯器或weaver代替Spring AOP或者除了Spring AOP之外,如果您的需求超出了Spring AOP提供的功能。
@Configurable注解,這章主要講的。
6. Spring AOP APIs
沒什么用這章。
前一章描述了Spring使用@AspectJ和基於模式的方面定義對AOP的支持。在本章中,我們將討論較低級別的Spring AOP API以及Spring 1.2應用程序中常用的AOP支持。對於新應用程序,我們建議使用前一章中描述的Spring 2.0及更高版本的AOP支持。但是,當您使用現有應用程序時(或者當您閱讀書籍和文章時),您可能會遇到Spring 1.2風格的示例。 Spring 5仍然向后兼容Spring 1.2,本章中描述的所有內容在Spring 5中都得到了完全支持。
7. Null-safety
9 spring xml文件的格式
這章就是講了spring的xml文件應該怎么搞。
疑惑
@EnableLoadTimeWeaving 注解或<context:load-time-weaver/>配置
講了織入可以分為:編譯器、類加載期、運行期(動態代理和cglib屬於這個)
Ltw屬於類加載期。
第二個url的例子自己跑了一遍,也結合第一個url的例子的說明,ltw可以起到這么一個作用:
同一份代碼、同一份配置,只需要在VM啟動參數中稍加變化,即可實現同一個應用包在不同環境下可以自由選擇使用使用AOP功能。https://sexycoding.iteye.com/blog/1062372
https://www.cnblogs.com/takumicx/p/10150344.html