想在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的值的大小,决定了是先通知再执行,还是先执行再通知-->
			
        <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 表示发生异常时通知,还有其他选择 -->
			
            <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>
还有一个执行通知的类
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("事务执行完成");
			
        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);
		
    }
		
}
这两个测试方法一个成功,一个不成功就可以测试出通知发生在不同的时间了。
			
 
一点感想:
			
就是在读Spring手册时不够认真,这个事务配置了好几天,都是不成功,在网上也没有找到合适的解决方法,最后又仔细的读了一次手册,终于成功!教训~!
	posted on 2007-06-02 11:29 
Libo 阅读(2092) 
评论(0)  编辑  收藏