Spring Bean是事物處理組件類和實體類(POJO)對象的總稱,Spring Bean被Spring IOC容器初始化,裝配和管理。在Spring IOC容器管理Bean時,需要了解Bean的類名、名稱、依賴項、屬性、生命週期以及作用域等信息。
Bean類的配置項
Spring IOC容器管理Bean時,需要了解Bean的類名、名稱、依賴項、屬性、生命週期及作用域等信息。爲此,Spring IOC提供了一系列配置項,用於Bean在IOC容器中的定義。
1、class:該配置項是強制項,用於指定創建Bean實例的Bean類的路徑。
比如以下配置中。class=org.springframework.scheduling.quartz.SchedulerFactoryBean,則表示Bean類的路徑。
2、name:該配置項是強制項,用於指定Bean唯一的標識符,在基於 XML 的配置項中,可以使用 id和或 name 屬性來指定 Bean唯一 標識符。
3、scope: 該配置項是可選項,用於設定創建Bean對象的作用域。
4、constructor-arg:該配置項是可選項,用於指定通過構造函數注入依賴數據到Bean。
如:
<bean id="connectionManager"
class="org.apache.commons.httpclient.MultiThreadedHttpConnectionManager">
<property name="params" ref="connectionManagerParams" />
</bean>
<bean id="httpClient" class="org.apache.commons.httpclient.HttpClient">
<constructor-arg>
<ref bean="connectionManager" />
</constructor-arg>
</bean>
5、properties:該配置項是可選項,用於指定通過set方法注入依賴數據到Bean。
6、 autowiring mode:該配置項是可選項,用於指定通過自動依賴方法注入依賴數據到Bean。
7、lazy-initialization mode:該配置項是可選項,用於指定IOC容器延遲創建Bean,在用戶請求時創建Bean,而不要在啓動時就創建Bean。
8、initialization:該配置項是可選項,用於指定IOC容器完成Bean必要的創建後,調用Bean類提供的回調方法對Bean實例進一步處理。
spring中bean的配置
三種方法:
1、基於XML的配置文件;
2、基於註解的配置;
3、基於Java的配置。
基於XML的配置文件
項目創建後,需要手動創建Spring配置文件,Spring配置文件默認名稱是applicationContext.xml,也可以用其他文件名稱代替。
(1)Spring配置文件的加載
xml是Spring最常見的配置源。加載Spring的配置文件有多種方式。Spring中的幾種容器都支持使用xml裝配bean,比如:
XmlBeanFactory:引用資源
ClassPathXmlApplicationContext: 編譯路徑,使用ClassPathXmlApplicationContext對象獲取,必須把applicationContext.xml放置到類的加載路徑中
FileSystemXmlApplicationContext:文件系統路徑
XmlWebApplicationContext是專爲Web工程定製的
還有一種情況是在web應用中,通過ContextLoaderListener可加載多個配置文件,在web.xml中利用<context-param>元數來指定多個配置文件位置。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext.xml
classpath:dubbo.xml
</param-value>
</context-param>
(2)xml中定義bean
如:
<bean id="scheduler"
class="org.springframework.scheduling.quartz.SchedulerFactoryBean"
destroy-method="destroy">
<property name="triggers">
<list>
<ref bean="MysqlIoTrigger" />
<ref bean="MysqlSqlTrigger" />
</list>
</property>
<bean>標籤用於定義Bean,各屬性說明如下:
① id:Bean的唯一標識,ApplicationContext對象可以通過id獲取該Bean的實例。
② calss:Bean類的存儲路徑。
<property>標籤用於從外部注入Bean的屬性值, <property>標籤各屬性說明如下:
① name:Bean類的屬性名稱。
② value:name所值屬性的值。
基於註解的配置
從 Spring 2.5 開始就可以使用註解來配置依賴注入。使用註解的方式使我們無需在XML中配置一個Bean引用,更加簡單和方便。
註解配置默認情況下在Spring中是關閉的,我們需要在配置文件中使用<context:annotation-config/>
激活它。另,在我們使用註解時一般都會配置掃描包路徑選項:如:<context:component-scan base-package="pack.pack"/>,該配置項其實包含了<context:annotation-config/> 的功能,因此當使用<context:component-scan/>後,即可將<context:annotation-config/>省去。
如:
import org.springframework.stereotype.Component;
@Component("userDao")
public class UserDao {
...
}
使用 @Component 註解在 UserDao 類聲明處對類進行標註,它可以被 Spring 容器識別,Spring 容器自動將 POJO 轉換爲容器管理的 Bean。它和以下 XML 配置是等效的:
<bean id="userDao" class="com.smart.anno.UserDao"/>
除 @Component 外,Spring還提供了3個功能基本和 @Component 等效的註解,分別用於對 DAO、Service及 Web 層的 Controller 進行註解。
@Repository:用於對 DAO 實現類進行標註。
@Service:用於對 Service 實現類進行標註。
@Controller:用於對 Controller 實現類進行標註。
之所以要在 @Component 之外提供這3個特殊的註解,是爲了讓標註類本身的用途清晰化,完全可以用 @Component 替代這3個特殊的註解。但是,我們推薦使用特定的註解標註特定的 Bean,畢竟這樣一眼就可以看出 Bean 的真實身份。當Bean的實現類是當前項目開發的,可以直接在Java類中使用基於註解的配置,配置比較簡單。
通過爲bean添加註解實現自動裝配
創建應用對象之間的協作關係的行爲稱爲裝配(writing),這是依賴注入的本質。如果所有的對象都是獨立的,彼此之間沒有任何依賴,那麼使用組件掃描就能自動化裝配bean。但是實際工作中,很多對象會依賴其他對象完成任務。這時候就需要能夠將組件掃描得到的bean和他們依賴裝配在一起。這就是自動裝配(autowiring)。
Spring中使用@Autowired註解來實現Bean的依賴注入。
如:
//①定義一個 Service 的 Bean
@Service
public class LogonService implements BeanNameAware {
//②分別注入logDao和userDao的Bean
@Autowired
private LogDao logDao;
@Autowired
private UserDao userDao;
}
在①處使用 @Service 將 LogonService 標註爲一個 Bean,在②處通過 @Autowired 注入 LogDao 及 UserDao 的 Bean。@Autowired 默認按類型(byType)匹配的方式在容器中查找匹配的 Bean,當有且僅有一個匹配的 Bean 時,Spring 將其注入 @Autowired 標註的變量中。
1)如果容器中沒有一個和標註變量類型匹配的 Bean,那麼 Spring 容器啓動時將報 NoSuchBeanDefinitionException 異常。如果希望 Spring 即使找不到匹配的 Bean 完成注入也不要拋出異常,那麼可以使用 @Autowired(required=false) 進行標註。在默認情況下,@Autowired 的 required 屬性值爲 ture,即要求必須找到匹配的 Bean,否則將報異常。
2)使用 @Qualifier 指定注入 Bean 的名稱:如果容器中有一個以上匹配的 Bean時,則可以通過 @Qualifier 註解限定 Bean 的名稱,如下所示。
基於java類的配置
定義一個配置類,用@Configuration註解該類,等價於XML裏的<beans>,用@Bean註解方法,等價於XML配置的<bean>,方法名等於beanId。方法必須提供Bean的實例化邏輯。
@Configuration
public class SpringConfig {
@Bean
public Service service(){
return new Service();
}
@Bean
public Client client(){
return new Client();
}
}
加載bean:
ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
Client client = context.getBean("client",Client.class);
Spring Bean的這三種配置方式,因爲XML配置較爲繁瑣,現在大部分開始用註解和java配置,一般什麼時候用註解或者java配置呢?
基本原則是:全局配置用java配置(如數據庫配置,MVC,redis等相關配置),業務Bean的配置用註解(@Service @Component@Repository@Controlle)。
Bean作用範圍及生命過程方法
通過註解配置的 Bean 和通過 <bean> 配置的 Bean 一樣,默認的作用範圍都是 singleton。Spring 爲註解配置提供了一個 @Scope 註解,可以通過它顯式指定 Bean 的作用範圍。
在使用 <bean> 進行配置時,可以通過 init-method 和 destory-method 屬性指定 Bean 的初始化及容器銷燬前執行的方法。Spring 從2.5開始支持 JSR-250 中定義的 @PostConstruct 和 @PreDestroy 註解,在 Spring 中它們相當於 init-method 和 destory-method 屬性的功能,不過在使用註解時,可以在一個 Bean 中定義多個 @PostConstruct 和 @PreDestroy 方法。