Spring中服配Service和Spring配置文件的整合
下面通过一个简单的实例来了解Spring的业务层即相关机制和配置
1、用户登录的UserService
package com.service; import com.domain.User; public interface UserService { boolean hasMatchUser(String userName,String password); User findUserByUserName(String userName); void loginSuccess(User user); }
2、Service实现
package com.service; import com.dao.LoginLogDao; import com.dao.UserDao; import com.domain.LoginLog; import com.domain.User; public class UserServiceImpl implements UserService { private UserDao userDao; private LoginLogDao loginLogDao; public boolean hasMatchUser(String userName, String password) { int matchCount =userDao.getMatchCount(userName, password); return matchCount > 0; } public User findUserByUserName(String userName) { return userDao.findUserByUserName(userName); } public void loginSuccess(User user) { user.setCredits( 5 + user.getCredits()); LoginLog loginLog = new LoginLog(); loginLog.setUserId(user.getUserId()); loginLog.setIp(user.getLastIp()); loginLog.setLoginDate(user.getLastVisit()); userDao.updateLoginInfo(user); loginLogDao.insertLoginLog(loginLog); } public void setLoginLogDao(LoginLogDao loginLogDao) { this.loginLogDao = loginLogDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
从上面的代码中我们可以看出:UserServiceImpl声明了userDao和loginLogDao两个属性,并提供了setXXX方法,这是为了通过Spring的配置文件完成DAO的注入。这里的两个属性和相应的setXXX方法都是Spring配置文件DAO注入值的接收器。此外,我们看不到任何的事物操作的代码,这是因为Spring让程序员从事务操作单调机械的代码中解脱出来,专注完成必不可少的工作。其他的由Spring容器来完成。通过Spring声明式事务配置即可以让业务类享受EJB声明式事务的优点。
接下来我们在Spring中为业务类UserService实现类实现事务管理能力和配置声明式事务。
3、Spring的事务管理和声明式事务配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans default-autowire="no"> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"> </property> </bean> <bean id="userServiceTarget" class="com.service.UserServiceImpl"> <property name="userDao" ref="userDao" /> <property name="loginLogDao" ref="loginLogDao"></property> </bean> <!-- 声明性事务 --> <bean id="userService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="transactionManager" /> <property name="target" ref="userServiceTarget" /> <property name="transactionAttributes"> <props> <prop key="findUserByUserName"> PROPAGATION_REQUIRED,readOnly </prop> <prop key="hasMatchUser"> PROPAGATION_REQUIRED,readOnly </prop> <prop key="loginSuccess">PROPAGATION_REQUIRED</prop> </props> </property> </bean> </beans>
在上面的配置文件中,作了以下几方面的配置:1是定义了一个基于数据源的DataSourceTransactionManager事务管理器,该事务管理器负责声明式事务管理,该管理器需要设置dataSource属性。在这个配置文件中没有定义,但已经在上一个博客(Spring的DAO装载)的配置中定义,在后面将讲述怎样将两个或多个配置文件在运行期整合在一起。所以这里就不进行配置,而是直接使用已经配置好的相应的BEAN ID。2是定义了业务类具体实现Bean。该类中有两个DAO属性,在这里进行属性的值的注入。3配置声明式事务。声明式事务可以配置3个属性:transactionManager(对目标类的方法进行事务管理)、target(需要代理的目标业务类)和transactionAttributes(定义目标业务类中的那些方法需要事务的支持)。在transactionAttributes中定义方法的事务控制属性。这里介绍几个常用的事务控制属性(事务传播类型):PROPAGATION_REQUIRED--较常用,表示业务方法在当前线程中查看是否有事务支持,有就利用这个事务,否则创建一个新的事务。readOnly——表示事务是只读事务,可以提高运行效率。
此外,在配置transactionAttributes中的方法名时,可以使用"*"通配符。
4、Spring配置文件的整合
我么可以在web.xml中进行配置来再Web容器启动时自动启动Spring容器。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dao.xml,classpath:service.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<!-- 使用自动启动的Servlet进行初始化 -->
<!-- servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet-->
<servlet>
<servlet-name>myweb</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>3</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>myweb</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
</web-app>
从上面的配置中我们可以看出:1是spring配置文件的整合是在<context-param> <param-value>classpath:dao.xml,classpath:service.xml</param-value>
</context-param>中用classpath:配置文件名表示一个配置文件,并用逗号分隔多个配置文件的方式来进行多个配置文件的整合,然后用一个Listener来监听这些配置。2是同Struts一样,加载一个Servlet来引入Spring。