Spring配置

Spring 最基本的的功能是提供通過配置管理任意類,提供了Bean管理容器。

這也是Spring最基礎,最核心的功能,在Spring框架中,一切皆爲Bean,實際上在我們的日常開發中,往往更多的是和Bean相關的開發,並且都是短生命週期,除了一些緩存功能,其他很多重要的功能都是由開源框架完成。

實現方式也是框架常用的反射機制,因此使用Spring前提在JVM啓動參數中不能加安全管理配置。Spring中所有的Bean相關配置均爲一個文件,非常集中,個人感覺這有利有弊,利大於弊。

統一配置比較方便集中,我最近的項目就是有很多子系統,除了一些公用的配置文件,還有很多子系統的配置文件,每次遷移環境是非常累的事,如果只有一個配置文件,那工作就會輕鬆多了。

缺點也就在於很集中,如果配置有誤,整個系統不可用,這種情況往往發生在系統升級階段,也比較少,即使出現問題也比較好定位。
Spring提供了Bean管理容器,這個功能可以大大簡化業務系統的配置開發工作。

個人感覺將來的開發工作更多的是配置,編寫業務相關的Bean以及業務方法,其他功能均會有很多優秀的開源框架實現,重要的工作是選擇符合項目的框架、熟悉框架,最重要的還是苦修內功,深入學習java,因爲萬變不如其中,再說開源不是萬能的,有時候還是要靠自己的。

Spring提供三種創建類實例方法:
a、通過構造函數,訪問屬性可以是任意
b、通過對應類的靜態工廠方法,注意不能是私有的
c、通過工廠類的實例工廠方法,是非靜態的方法

1、bean節點相關主要屬性:
id/name 實例名/別名
class 必須、類全名
singleton 是否爲單實例,默認爲true
init-method 初始化方法
depends-on 指定依賴Bean,實現在被依賴Bean實例創建前,對依賴的一個或多個Bean的實例化,
init-method在對應Bean實例已經創建後調用
destroy-method 釋放回調方法,常用於資源釋放
dependency-check 依賴檢查
parent 指定父Bean實例,減少因繼承關係的重複配置
說明除配置init-method,destory以外,可以在對應Bean中實現InitializingBean,DisposableBean兩個接口方法
Spring容器不負責管理非單實例的Bean
配置bean事項:
1)、注意在通過構造器參數匹配時,必須指定參數的序號,同時建議明確說明類型,
<constructor-arg index="0"><value>128</value></constructor-arg>
<constructor-arg index="1"><value>teststring</value></constructor-arg>
最好說明相關參數類型類型
<constructor-arg index="0" type="int"><value>128</value></constructor-arg>
<constructor-arg index="1" type="java.lang.String"><value>teststring</value></constructor-arg>
可以使用簡化配置
<constructor-arg index="0" type="int" value="128"/>
<constructor-arg index="1" type="java.lang.String" value="testString"/>

2)、屬性爲空
<property name="pro1><null/></property>
3)、空串
<property name="pro1><value></value></property>
2、常用elements
bean | ref | idref | value | null | list | set | map | props
說明:
bean 創建一個新的bean實例
ref 引用已經創建的bean實例
value 簡單數據類型
null 空指針
list 創建java.util.ArrayList對象實例
set 創建java.util.LinkedHashSet對象實例
map 創建java.util.LinkedHashMap對象實例
props 創建java.util.Properties實例
list,set,map可以多層嵌套配置

遺留問題:
idref 配置沒有起作用,類似value配置,測試輸出爲字符串對象,是否配置不正確?

上述配置範圍基本覆蓋了我們開發時的bean使用情況,詳見配置可以參考dtd
http://www.springframework.org/dtd/spring-beans.dtd

ApplicationContext 繼承於BeanFactory相關接口,針對企業應用級的,佔有內存較多
BeanFactory 提供配置框架和基本功能,適用於對內存有限制的相關應用
功能:
1)、提供消息訪問,ApplicationContext 本身繼承於MessageSource接口,
ApplicationContext 加載時查找對應的MessageSource Bean, bean id 必須爲messageSource
Spring框架提供兩個MessageResource實現:
org.springframework.context.support.ResourceBundleMessageSource
org.springframework.context.support.StaticMessageSource
2)、事件傳遞
3)、使用資源

Spring註釋與簡化配置

在Spring 2.5及以後的版本中,提供了註釋和命名空間來簡化Spring的配置。下面是一些常用配置分享。

1、@Autowired註釋
以前給一個Bean配置屬性時,Bean必須配置<property name="propName" ref="beanId"/>,然後在Java文件,還必須增加屬性propname的getter和setter方法。
有了@Autowired註釋後,我們可以簡化配置文件和getters和setters方法。
1)註釋屬性
@Autowired
private BeanClassName propName;
當然,我們還必須告訴Spring容器,當它啓動時,就去掃描所有的Bean,然後自動注入。
<!-- 對具有@Autowired註釋的Bean進行注入 -->
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
我們也可以註釋構造函數和方法。
2)註釋構造函數
@Autowired
public MainBean(PropBeanA propBeanA, PropBeanB propBeanB){
this.propBeanA = propBeanA;
this.PropBeanB = PropBeanB ;
}
3)註釋方法
@Autowired
public void setPropBean(PropBean propBean) {
this.propBean = propBean;
}
4)@Autowired的相關屬性
在默認情況下使用@Autowired註釋進行自動注入時,Spring容器中匹配的候選Bean數目必須有且僅有一個。當Springp容器找不到一個匹配的Bean時(可能是沒有配置該Bean或是Bean的屬性名寫錯了),Spring容器將拋出BeanCreationException異常,並指出必須至少擁有一個匹配的Bean。
(1)當Bean是可選的,或是不能確定Bean一定有,可以用@Autowired(required = false),這樣在找不到匹配Bean 時也不報錯,該屬性默認爲true。
(2)與上面的相反,當Bean有多個時,我們可以通過@Qualifier("beanId")還唯一確定一個所引用的Bean,與@Autowired配合使用,它也有三種使用的地方。

2、@Component註釋
雖然我們可以通過@Autowired在Bean類中使用自動注入功能,但是Bean還是在XML文件中通過<bean>進行定義的,通過@Component註釋可以實現無需在配置文件中配置Bean的目的。
import org.springframework.stereotype.Component;
@Component
public class BeanClassNameA {
// ......
}
使用@Autowired
@Component
public class BeanClassNameB {
@Autowired
private BeanClassNameA propBeanA;

// ......
}
因爲沒有配置,我們必須告訴Spring容器啓用類掃描機制並自動注入了:
<context:annotation-config />
前面的AutowiredAnnotationBeanPostProcessor可以去掉了,這行的作用後面介紹。
1)@Component有個可選參數,指定Bean的名稱@Component("beanId")
2)與@Component配合使用,可以通過@Scope指定Bean的作用範圍,比如:@Scope("prototype")

3、其他註釋
Spring除了提供@Component註釋外,還定義了幾個註釋:@Repository、@Service 和 @Controller。
在目前的Spring 2.5中,這3個註釋和@Component是等效的,但是從註釋類的命名上,很容易看出這3個註釋分別和持久層、業務層和控制層(Web 層)相對應。雖然目前這3個註釋和@Component相比沒有什麼新意,但Spring將在以後的版本中爲它們添加特殊的功能。所以,如果 Web 應用程序採用了經典的三層分層結構的話,最好在持久層、業務層和控制層分別採用@Repository、@Service和 @Controller對分層中的類進行註釋,而用@Component對那些比較中立的類進行註釋。

4、<context:annotation-config />
<context:annotation-config />將隱式地向Spring容器註冊 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 RequiredAnnotationBeanPostProcessor這4個BeanPostProcessor。

5、<context:component-scan base-package="......" />
通過<context:component-scan base-package="com.packname.common" />,Spring會遞歸掃描類註釋。
具體的說明可以參考:http://springindepth.com/book/annotation-based-bean-config-ioc-container-configuration.html

6、JavaEE應用@Controller
在使用SpringMVC中,可以通過@Controller簡化配置
@Controller
@RequestMapping("/welcome.htm")
public class SomeNameController {
@RequestMapping(method = RequestMethod.GET)
public void doGet(ModelMap model, WebRequest request) {
// ...
}
}
關於@Controller,在以後的文章中介紹,敬請關注。

7、簡化配置文件
對於屬性,我們一般都是通過以下配置的:
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
簡化之後爲:
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
使用方法介紹,我相信就沒必要了,注意這兩種方式可以一起使用的。

8、命名空間
在以上的<context:.... />和<bean id=".." p:name-ref="" />中,我們用到了context和p命名空間,因此必須在配置文件中申明,我的如下:
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
default-autowire="byName">
XSD文件版本小技巧:不要增加版本(如直接使用spring-context.xsd),當然要加也是spring-context-2.5.xsd

由於介紹內容比較多,感覺都比較空,還有一些沒有介紹具體:
(1)JavaEE的註釋,主要是@Controller;
(2)JPA註釋,@Entity,@Table;
(3)JSR-250的註釋,@Resource、@PostConstruct、@PreDestroy等。

下面貼出我的Spring配置文件的內容。
<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:osgi="http://www.springframework.org/schema/osgi" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"
default-autowire="byName">

<!-- Activates annotation-based bean configuration -->
<context:component-scan base-package="com.alipay.common" />

<!-- DataSource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/work_shop?useUnicode=true&amp;characterEncoding=UTF-8" />
<property name="username" value="root" />
<property name="password" value="manager" />
</bean>

<!-- SqlMapClient -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocations">
<list>
<value>classpath:sqlmap/sqlmap-config.xml</value>
</list>
</property>
</bean>

<!-- SqlMapClientDAO -->
<bean id="sqlMapClientDAO" abstract="true" p:dataSource-ref="dataSource"
p:sqlMapClient-ref="sqlMapClient" />

<!-- TransactionTemplate -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />

<!-- TransactionManager -->
<bean id="mockTransactionTemplate"
class="org.springframework.transaction.support.TransactionTemplate"
p:transactionManager-ref="transactionManager" />

<!-- DAO -->
<bean id="siteUserDAO" class="com.alipay.dal.ibatis.IbatisSiteUserDAO"
parent="sqlMapClientDAO" />
<!-- END OF DAO -->

<!-- MANAGER -->
<bean id="siteUserManager" class="com.alipay.biz.manager.impl.SiteUserManagerImpl" />
<!-- END OF MANAGER -->
<!-- FACADE-->
<!-- END OF FACADE-->
<!-- OSGI SERVICE-->
<!-- END OF OSGI SERVICE-->
</beans>

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