想在Service 層配置事務,Spring 好象是要求必須用接口,因為我沒用接口時沒配置成功.
一個IService 接口.聲明了所有Service層公共的方法,比如save、delete 等。
public
interface IService {
????public
int count(FindCriteria fc);
?
????public List find(FindCriteria fc);
?
????public Serializable save(Object object) throws UnsupportedOperationException;
}
?
UserService 接口,聲明UserService 的所有方法。還要 extends IService
public
interface UserService extends IService {
?
????public User login(User user);
????
}
?
UserService接口的實現類.
public
class UserServiceImpl implements UserService {
?
????/**
???? *
登錄
???? *
???? *
@param
user
???? *
@return
校驗成功的User實例
???? */
????public User login(User u) throws UnsupportedOperationException {
????????// throw new UnsupportedOperationException();
????????User user = (User) userDao.get(User.class, u.getId());
????????log.debug("get user is " + user);
????????if (user != null && user.getPassword().equals(u.getPassword()))
????????????return user;
????????return
null;
????}
?
//其他實現省略…
}
完整的applicationContent.xml
<?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-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
?
????<!-- 連接屬性 -->
????<bean id="propertyConfigurer"
????????class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
????????<property name="location" value="WEB-INF/jdbc.properties" />
????</bean>
?
????<!-- 數據源 -->
????<bean id="dataSource"
????????class="org.apache.commons.dbcp.BasicDataSource">
????????<property name="driverClassName" value="${jdbc.driver}" />
????????<property name="url" value="${jdbc.url}" />
????????<property name="username" value="${jdbc.user}" />
????????<property name="password" value="${jdbc.password}" />
????</bean>
?
????<!-- hibernate sessionFactory -->
????<bean id="sessionFactory"
????????class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
????????<property name="dataSource" ref="dataSource" />
????????<property name="hibernateProperties">
????????????<props>
????????????????<prop key="hibernate.dialect">
????????????????????${hibernate.dialect}
????????????????</prop>
????????????????<prop key="hibernate.show_sql">true</prop>
????????????????<prop key="hibernate.query.substitutions">
????????????????????true 1, false 0, yes 'Y', no 'N'
????????????????</prop>
????????????????<prop key="hibernate.jdbc.fetch_size">50</prop>
????????????????<prop key="hibernate.jdbc.batch_size">25</prop>
????????????</props>
????????</property>
????????<property name="annotatedClasses">
????????????<list>
????????????????<value>cn.xiangyunsoft.busniess.model.Rose</value>
????????????????<value>cn.xiangyunsoft.busniess.model.User</value>
????????????????<value>cn.xiangyunsoft.busniess.model.Department</value>
????????????</list>
????????</property>
????</bean>
?
????<!-- 配置事務管理 -->
?
????<!-- 事務通知類 -->
????<bean id="profiler"
????????class="cn.xiangyunsoft.busniess.service.SimpleProfiler">
????????<!-- order 值可以決定通知的先后順序 ,與后面的order的值的大小,決定了是先通知再執(zhí)行,還是先執(zhí)行再通知-->
????????<property name="order" value="2" />
????</bean>
?
????<bean id="transactionManager"
????????class="org.springframework.orm.hibernate3.HibernateTransactionManager">
????????<property name="sessionFactory" ref="sessionFactory" />
????</bean>
????<tx:advice id="txAdvice" transaction-manager="transactionManager">
????????<!-- the transactional semantics... -->
????????<tx:attributes>
????????????<!-- 以get 、 find 開頭的方法是只讀事務 -->
????????????<tx:method name="get*" read-only="true" />
????????????<tx:method name="find*" read-only="true" />
????????????<!-- 其他方法是默認 -->
????????????<tx:method name="*" />
????????</tx:attributes>
????</tx:advice>
?
????<aop:config>
????????<!-- 此處的IService 是表示對所有實現IService接口的類管理事務 -->
????????<aop:pointcut id="serviceOperation"
????????????expression="execution(* cn.xiangyunsoft.busniess.service.IService.*(..))" />
????????<aop:advisor advice-ref="txAdvice"
????????????pointcut-ref="serviceOperation" order="1" />
????????<aop:aspect id="profilingAspect" ref="profiler">
????????????<!-- -->
????????????<aop:pointcut id="serviceMethodWithReturnValue"
????????????????expression="execution(!void cn.xiangyunsoft.busniess.service..*Service.*(..))" />
????????????<!-- 通知類型為after-throwing 表示發(fā)生異常時通知,還有其他選擇 -->
????????????<aop:after-throwing method="profile"
????????????????pointcut-ref="serviceMethodWithReturnValue" />
????????</aop:aspect>
????</aop:config>
?
</beans>
Service 層的bean 在另一個beans.xml文件配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
????xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
????<bean id="userService"
????????class="cn.xiangyunsoft.busniess.service.UserServiceImpl">
????????<property name="userDao" ref="userDao"></property>
????</bean>
????<bean id="userDao"
????????class="cn.xiangyunsoft.busniess.dao.UserDao">
????????<property name="sessionFactory" ref="sessionFactory"></property>
????</bean>
</beans>
還有一個執(zhí)行通知的類
public
class SimpleProfiler implements Ordered {
?
????private
int
order;
// allows us to control the ordering of advice
public
int getOrder() {
return
this.order;
}
public
void setOrder(int order) {
this.order = order;
}
?
// this method is the around advice
public Object profile(ProceedingJoinPoint call) throws Throwable {
????System.out.println("事務執(zhí)行完成");
Object returnValue;
StopWatch clock = new StopWatch(getClass().getName());
try {
clock.start(call.toShortString());
returnValue = call.proceed();
} finally {
clock.stop();
System.out.println(clock.prettyPrint());
}
return returnValue;
}
}
?
測試類:
public
class BaseServiceTest extends AbstractTransactionalSpringContextTests {
????protected String[] getConfigLocations() {
????????return
new String[] { "classpath:/applicationContext_Test.xml",
????????????????"beans.xml" };
????}
}
public
class UserServiceTest extends BaseServiceTest {
?
????private UserService userService;
?
????public
void setUserService(UserService userService) {
????????this.userService = userService;
????}
?
????public UserService getUserService() {
????????return
userService;
????}
?
????@Test
????public
void testLogin() {
????????User user = new User("adm");
????????user.setPassword("admin");
????????userService.login(user);
????}
?
????@Test
????public
void testSave() {
????????User user = new User("122");
????????user.setName("abc");
????????userService.save(user);
????}
}
這兩個測試方法一個成功,一個不成功就可以測試出通知發(fā)生在不同的時間了。
?
一點感想:
就是在讀Spring手冊時不夠認真,這個事務配置了好幾天,都是不成功,在網上也沒有找到合適的解決方法,最后又仔細的讀了一次手冊,終于成功!教訓~!
posted on 2007-06-02 11:29
Libo 閱讀(2089)
評論(0) 編輯 收藏