<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">題目如此啊,但不一定每個人的情況都會和我的一樣,感覺這是個非常蛋疼的問題,困擾了我好幾天。</span>
我在做一個SSH集成CXF用於實現web service的服務器框架。實際上是用spring+hibernate集成CXF,沒用到Struts。之前用過SSH,但沒有完整地自己搭建一次SSH框架,之前只是在別人搭好的框架上進行頁面開發。沒想到自己搭一次,各種問題。
我看了spring的事務管理的幾種方法,大概有五種,但是感覺不習慣第一種 每一個bean都有一個代理,和不習慣第五種 註解的方式,覺得麻煩。就不斷地在用二三四的方法嘗試,就分別是每一個bean共享一個代理、攔截器、和tx標籤配置的攔截器,三種方法不斷地嘗試,但都共有一個問題,spring的依賴注入失效。
具體情況其實如我發的求助帖子:http://bbs.csdn.net/topics/391008520
開始的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="user" value="root" />
<property name="password" value="moment_root" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/moment" />
</bean>
<!--LocalSessionFactoryBean 用來加載Hibernate配置文件 , 此Bean 就是sessionFactory類型 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<!-- 需要指定Hibernate配置文件, -->
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<!-- 獲取連接池 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!--定義Hibernate的事務管理器HibernateTransactionManager -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<!-- 依賴注入上面定義的sessionFactory -->
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!--定義Spring的事務攔截器TransactionInterceptor -->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 依賴注入上面定義的事務管理器transactionManager -->
<property name="transactionManager" ref="transactionManager" />
<!-- 定義需要進行事務攔截的方法及所採用的事務控制類型 -->
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>
<!-- 定義BeanNameAutoProxyCreatorf進行Spring的事務處理 -->
<bean
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 針對指定的bean自動生成業務代理 -->
<property name="beanNames">
<list>
<value>*Service</value>
<value>*Dao</value>
</list>
</property>
<!-- 這個屬性爲true時,表示被代理的是目標類本身而不是目標類的接口 -->
<property name="proxyTargetClass">
<value>true</value>
</property>
<!-- 依賴注入上面定義的事務攔截器transactionInterceptor -->
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<!-- DAO層事務定義 -->
<bean id="SignInDao" class="com.moment.dao.userInfo.SignInDao" lazy-init="default" autowire="default">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- service層事務定義 -->
<bean id="SignInService" class="com.moment.service.userInfo.SignInService">
<property name="SignInDao" ref="SignInDao" />
</bean>
<!-- Action層對應service層的事務定義 -->
<bean id="/SignInImpl" class="com.moment.impl.userInfo.SignInImpl" scope="prototype">
<property name="SignInService" ref="SignInService" />
</bean>
</beans>
我自己感覺配置是沒什麼問題的,但是在Action層直接使用service層對象或者service層使用Dao層對象,都會報空指針異常,開始想,這也沒什麼,大不了我都自己初始化對象,實例化一下就好了,但是Dao層沒辦法啊,Dao層無法獲取session,也就沒辦法數據庫操作了。
然後,這個問題,困擾了我好幾天,我不斷地嘗試不同的配置方式,不斷地修改配置文件,看了網上好多資料,但是感覺,沒啥問題,但是問題還是一樣的,後來找了一份參考。問題一下解決了。
方法就是在每一個需要依賴注入的對象的set方法前加一個@Resource
如我在Action層要依賴注入service層對象:
@Autowired
private SignInService signInService;
public SignInService getSignInService() {
return signInService;
}
@Resource
public void setSignInService(SignInService signInService) {
this.signInService = signInService;
}
service層我也同樣加上,然後神奇地發現問題解決了。解決的很突然,暫時也不知道原因。
或許別人的原因和我的也不一樣,但我先記錄一個吧,以後沒準再碰到。