javascript
factorybean 代理类不能按照类型注入_《Spring入门经典》:使用Spring进行依赖注入
第二章:使用Spring進行依賴注入
重點:配置并使用Spring容器
使用不同類型的配置元數據來配置Spring容器
理解依賴解析
了解自動裝配的優缺點
在容器中執行顯式Bean查找
學習不同的Bean實例化方法
理解指定了作用域的Bean以及可用的作用域
學習延遲Bean創建的工作原理
理解生命周期回調
使用Bean定義配置文件來創建有條件的Bean配置
2.1.1配置元數據
需要向Spring容器提供相關信息,以便實例化Bean,并指定如何對這些Bean進行裝配,所提供的信息被稱為配置元數據。
配置元數據的傳統格式是XML,除此之外還有基于注解和基于java的配置元數據。基于XML:
<?xml version="1.0" encoding="UTF-8"?>基于注解:
@Service("accountService")public class AccountServiceImpl implements AccountService { private AccountDao accountDao; @Autowired public void setAccountDao(AccountDao accountDao) { this.accountDao = accountDao; }}@Repository("accountDao")public class AccountDaoImpl extends JdbcDaoSupport implements AccountDao {}基于java:
@Configurationpublic class BeanConfig{ @Bean public AccountService accountService(){} @Bean public AccountDao accountDao(){}}2.1.2配置和使用容器
默認情況下,每一個Bean都有一個被稱作單實例作用域的單個實例。Spring在運行時動態地擴展@Configuration并且使用@Bean注解來重寫工廠方法。因此,不管是從類中多次調用工廠方法,還是從其他@Configuration類中多次調用工廠方法,在第1次創建了Bean實例之后就不會再創建任何新的Bean實例,對于連續調用,工廠方法將會返回相同的Bean實例。
2.2.1Setter注入是在Bean實例創建完畢之后執行的。
2.2.2構造函數注入是在組件創建期間被執行。
2.2.3循環注入
構造函數注入無法解決此問題,因為組件創建期間互相依賴,Spring無法實例化任一個Bean;Spring通過使用Setter注入允許循環注入,因為組件先創建,再設置屬性。
2.2.4依賴解析過程
Spring容器的啟動過程大致分為兩個主要階段,第一階段容器處理配置元數據并建立元數據中存在的Bean定義,在該過程中會對這些Bean定義進行驗證。例如,檢查是否向和元素提供了正確的Bean應用等。此步驟中Bean并沒有被創建相關的屬性,也沒有被注入。
第二階段首先完成Bean的創建,然后完成依賴注入。實際上并不是所有的Bean都被創建,在容器啟動期間僅創建了無狀態作用域的Bean。
一個Bean在被完全創建且自己的依賴項被注入之前是不會作為一個依賴項被注入到其他的Bean中去的。
2.2.5重寫定義
重寫Spring容器中的Bean定義是可能的,每個Bean都有身份,而Bean的名稱定義了自己的身份,如果創建了一個Bean定義,而該Bean的名稱已經賦予了其他的定義,那么第二個定義將重寫第一個定義。
Spring容器提供了兩種不同形式Bean重寫機制。第一種重寫發生在配置元數據文件級別。ApplicationContext創建期間指定這些文件或者類組合在一起。Spring容器將來自不同配置源的所有Bean合并在一起,合并期間,配置源的順序是非常重要的。如果有兩個不同的配置源中定義了同名的Bean,那么根據給定的順序第二個Bean定義將重寫第一個Bean定義。
第二種類型的Bean重寫發生在容器級別。ApplicationContext可能有父ApplicationContext,在父ApplicationContext實例和子ApplicationContext實例中共存兩個同名的Bean實例是完全可能的。
在Web應用中,通常ContextLoaderListener創建父ApplicationContext,使用DispatcherServlet創建子的ApplicationContext。DispatcherServlet確認由ContextLoaderListener創建的ApplicationContext實例,并在創建自己的ApplicationContext實例時將其作為父ApplicationContext。
2.2.6使用depends-on特性
例如一個執行JVM級別初始化的Bean必須在其他Bean之間被創建,因為這些Bean在被初始化之前必須先完成JVM的初始化。此時,可以在基于XML配置中使用元素的depends-on特性來制定b和c在a創建之前被創建,如下:
Bean通過名稱進行區分。每一個Bean至少有一個名稱,如果開發人員沒有為其命名,Spring容器將會為其分配一個內部名稱。通過Bean的名稱,可以從其他Bean定義中或者利用顯示查找從應用程序代碼中引用Bean。
在基于XML的配置中使用id特性,將一個名稱分配的一個Bean。在相同的XML文件中不能復制同一個名稱。然而在其他XML文件中可以將相同的名稱分配給另一個Bean定義。這種情況下,Bean重啟機制開始發揮作用。
2.3.1命名
如果想在Bean定義中為其分配多個名稱,可以使用name特性,在name特性中可以使用空格、逗號、分號來分離給定Bean定義的多個名稱。
2.3.2Bean實例化方法
第一種調用相關類中一個可用的構造函數;
第二種調用靜態或實例工廠方法;
第三種使用Spring自帶的FactoryBean接口。
public interface FactoryBean { T getObject() throws Exception; Class> getObjectType(); boolean isSingleton();}這是一個特殊接口,在運行時,Spring容器會發現實現了該接口的Bean定義類。如果該類是FactoryBean類型的,則通過調用其getObject()方法創建該Bean。而所創建的Bean的類型由getObjectType()返回的類型確定,而不是由getObjectType()實例類確定。該方法通常被Spring Framework所使用。
2.3.3Bean作用域
由Spring容器創建的Bean的生存期被稱為Bean作用域。在默認情況下,由Spring容器創建的所有Bean都有Singleton作用域。換句話說,針對一個Bean定義是創建了一個Bean實例,并且Spring容器可以在整個應用程序生存期中使用該實例。當不同的Bean與不同的層(控制層、服務層和數據訪問對象層)相對應時,可以使用Singleton作用域。此時創建的實例都是無狀態實例。
2.3.4延遲初始化
默認情況下,Spring容器在啟動階段創建,該過程被稱為預先Bean初始化。其優點是可以盡早發現配置錯誤。
在另一方面如果存在大量的Bean定義或者一些特殊的Bean,例如hibernate SessionFactory(這些Bean的初始化會占用大量的時間),那么初始化會降低啟動速度。一些Bean可能是在特定的場合或備選方案中使用,而其他情況并不需要。在這種情況下,預先初始化可能會導致不必要的堆內存消耗。
Spring支持延遲Bean初始化。如果開發人員將Bean配置為延遲創建,那么容器將會延遲Bean的創建,直到真正需要才創建。通過從一個已經創建的另一個Bean中的引用,或者在應用程序代碼中執行顯示查找,都可以觸發創建。
@Entity@Proxy(lazy = false)@Table(name = "book")public class Book implements Serializable {……}2.3.5生命周期回調
Bean可以定義回調方法。這些方法可以在生命期的任何特定時間點由容器調用。這些時間點從Bean實例化后開始,直到他們定義的作用域終止。這些方法也稱為初始化方法和銷毀方法。
基于XML配置的元素init-method和destory-method特性,他們接收Bean類中的方法名稱作為特性值;
基于注解有PostConstruct和PreDestroy,當將這兩個注解分別放置在init和destory方法之上時,在Bean創建和銷毀時也會調用這兩個方法。
@PostConstructpublic void init() throws Exception { log.info("Test init start."); ……; log.info("Test init end.");}@PreDestroypublic void destory() throws Exception{ log.info("Test destory start."); ……; log.info("Test destory end.");}第三種選擇是Bean實現InitializingBean接口,Spring容器在屬性注入完畢之后調用afterPropertiesSet方法初始化;Bean實現DisposableBean接口,那么Bean銷毀之前調用destroy方法。
public interface InitializingBean { void afterPropertiesSet() throws Exception;}public interface DisposableBean { void destroy() throws Exception;}#Spring##程序員#
總結
以上是生活随笔為你收集整理的factorybean 代理类不能按照类型注入_《Spring入门经典》:使用Spring进行依赖注入的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python如何调用日期函数_当前时间等
- 下一篇: springboot 读取配置文件_使用