Spring5 註解編程基礎組件(Annotation API)

1.配置組件(Configure Components)

(1)@Configuration:把一個類作爲一個IoC容器,他的某個方法頭上如果註解了@Bean,那麼就會作爲bean存在spring容器中

以前我們寫在配置文件,配置一個個bean,現在使用這個註解即可

圖一創建的類使用了註解@Configuration,然後裏面@Bean註解了一個方法 

@Bean註解方法的返回值就作爲實例存在ioc容器中了

圖二中我們獲取app然後獲取實例即可

關於圖一使用new 對象其實不是真的new出來的,是使用原型模式生成的,所以new幾次都是同一實例

如下圖

  @Bean("person111")這裏其實就是不使用方法名爲實例名,而重新定義了一個

我們再次用方法名獲取實例就會報錯

改爲person111又正常獲取

總結下:優先取bean註解的value,其次是取方法名

(2)@ComponentScan

就跟之前xml 中的<context:component-scan> 效果一樣 ,註解在某類上時會掃描該類所在包下的所有類

如果你定義了包路徑的話就掃描該路徑下的所有組件,記住是組件,不是所有類,比如@Controller,@Service這種,或者@Component這種

可以看到person類有被掃描到

圖一中@ComponentScan("com.robert.annotations.project")表示掃描該路徑下所有組件加載到ioc容器中,正常來說該路徑下的Person類不在此範圍裏,這裏我們手動加了@Component註解,使其被掃描

但是,開發中,我們可能某些包的某些類不想掃描,這裏我們就可以用過濾器excludeFilters 和 includeFilters 

這裏就不演示 

@ComponentScan(value = "io.mieux",
        excludeFilters = {@Filter(type = FilterType.ANNOTATION,
        value = {Controller.class})})

意思就是我掃描io.mieux下的所有沒有被@Controller註解的類

這裏除了使用註解過濾,當你規則比較複雜的時候,還可以使用正則表達式啊,過濾類啊等待,

好了,第二個註解@ComponentScan我就說到這,總的來說就是掃描一些類,將這些類的實例放到IoC容器中,

然後我要用的時候不需要new,使用依賴注入即可

(3)@Scope 

該註解用於指定作用域的,用在類上,這個註解也不復雜哦

現在我們把@Scope("prototype")註解註釋

 

然後從容器中獲取實例,可以看到是獲取的相同的

現在解開註釋

 發現是不同的實例了

這裏關於這個註解不多說

有四種場景:

不寫時默認爲單例

然後@Scope("prototype")代表每次獲取實例創建新的

@Scope("request")表示在同一請求中,只創建一個實例

@Scope("session") 類似,表示在同一session中單例

第三個註解就到這

(4)@Lazy

延時加載本來是在容器啓動時就創建實例,使用該註解後,在調用該對象方法或者說用到該對象時才創建實例,延時加載是單例模式

上兩圖,先分別在實例創建與測試時容器創建的時候加上打印語句

可以看到是先將實例放入IoC,然後再打印初始化IOC容器

 

現在加上@Lazy註解

再看控制檯,可以看到使用時才創建對象並加入IOC容器,怎麼說呢,懶加載就像之前說的懶漢模式,用的時候我才創建,這樣當你項目龐大時能提升不少性能

(5)@Conditional

意思是按照一定的條件判斷是否給容器註冊bean

使用@Conditional註解要配合Condition類,我們這裏先定義倆Condition

然後測試,此demo實現操作系統爲windows時創建james,爲linux時創建tom

修改vm參數,模擬linux操作系統 

此時測試創建tom實例

(6)@Import

這個作用就是導入外部資源,相當於手動指定第三方資源,把其實例加載到IoC中

配置類,還是配置了一個bean person

測試類,打印輸出掃描到的類 

新建Cat類

測試類中使用@Import(value = {Cat.class})

發現打印的Ioc中的bean多了Cat類

 

還有一種方式,可以自定義ImportSelector

比如說我只想導入某幾個類,或者我只想導入類名包含 "AP"的類

新建dog跟mouse類

自定義importSelector,import註解裏的數組裏加上

測試,可以看到,IoC中多了mouse跟dog類實例

繼續,使用import註解還有第三種方式,這種更加體現了註解編程的靈活度

自定義MyImportBeanDefinitionRegistrator,裏面邏輯是我如果Ioc註冊列表裏有Mouse跟Dog我就註冊一個新的實例catt

測試發現成功註冊catt

總結下,關於註冊bean到IoC容器,有三種方式

1.@Bean 加一個註解一個

2.@ComponentScan可以註冊某個包下的一堆組件

3.@Import  有三種方式(1.Xx.class,2.XximportSelector,3.XxImportBeanDefinitionRegistrator)

其實還有第四種

關於面試問的BeanFactory與FactoryBean區別:

其實FactoryBean就是spring內部的一個Bean,不過他的職責是負責將bean註冊到IoC容器中,

而我們獲取bean時使用FactoryBean即可獲取

先整個MyFactoryBean,可以看到實現了三個方法,分別爲返回對象,返回對象類型,是否單例

在配置類中多加一個Bean

可以看到返回的是MyFactoryBean對象,可以看到其實獲取到的是monkey實例

也就是說,FactoryBean的作用就是註冊實例,而我們設置的單例爲true,也可以看到測試結果中倆對象相同

好了@Import註解到此結束

(7)bean的生命週期

配置階段只剩最後一類註解了就是關於bean的生命週期

新建Car類

 

配置類

initMethod = "start",destroyMethod = "stop",表示初始化與銷燬對象時分別調用對應的方法

測試下

然後是第二種

第二種是直接實現倆接口

重寫destroy與afterPropertiesSet方法

配置文件改回去

Car類要加@Component註解 

配置類加掃描組件的註解

再次運行測試方法

結果相同

現在說第三種

如圖,使用註解@PostConstruct 與@PreDestroy

 

第四種方式

自定義MyBeanPostProcessor繼承BeanPostProcessor接口

這種方式最靈活,這樣寫定義類,可以在其中獲取所有bean,可以針對性的處理

測試正常

2.賦值組件(Injection Components)

這一部分的註解是日常開發中用的最多的,我先全部列舉,你應該會有幾個熟悉的

@Component,@Service,@Controller,@Repository,@Value,@Autowired,@PropertySource,@Qualifier,@Primary,@Resource,下面我一個個來講解

@Component 泛指組件,當你的組件不好歸類時,就用它進行標註

@Service,@Controller,@Repository都是@Component的子類,這四個註解都只是一個標註的作用,不過標註的對象不同

分別標註業務層,控制層,數據訪問層

 

然後是@Value,這個註解就是起個賦值的作用

定義了一個類Bird,分別三種使用@Value的方式給屬性賦值,分別是直接賦值,EL表達式,獲取配置文件屬性

 

使用配置文件屬性時,記得在配置類上加上@PropertySource(value = "classpath:config.properties")

然後測試時可以看到獲取對象的屬性被成功賦值

剛剛這塊就包含倆註解,@Value與@PropertySource

 

下面說下autowired,這個註解就是注入

使用autowired註解注入,

測試類中掃描這三個類的組件,其中編寫service類時打印了dao的實例

說明我們注入DemoService類中的DemoDao的實例就是IoC中的

 

接下來是@Qualifier註解,當你不想要注入Ioc中的bean時,使用這個註解可以注入你指定的bean

這裏我在DemoDao中整了個flag,值爲1,正常注入DemoDao的話flag爲1

 

我現在自定義bean,裏面的flag爲2

 

那麼這個時候可以用Qualifier

 

測試可以看到我們注入的就是flag爲2的自定義bean

 

把自定義裏的flag改爲4

 

 

 

使用@Resource註解

@Resource是針對所有的資源,比@Autowired與@Qualifier優先級更高

 

最後一個註解@Primary 優先 當倆bean名稱相同時,其中一個加上@Primary註解,將獲得優先權

3.織入組件(Weave Components)

@AppllicationContextAware:這是spring中的上下文環境對象,可以通過他得到IoC中的所有bean

還有一個是BeanDefinitionRegistryPostProcessor, 這個是用來註冊額外的BeanDefinition的

 BeanDefinition就是Bean配置的封裝而已

4.切面組件(Aspect Components)

@Transactional 配置事務信息

@EnableTransactionManagement 添加事務管理,就是開啓事務

 

 

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