service层,然后写service的测试类,然后我会加入一个拦截器:拦截service的请求,这个拦截器是针对方法的拦截,这个拦截器里面我们可以知道调用到了那个service类,那个method,可以截获到传入的参数,也能截获到返回值。我在公司的项目里的aop就会拦截到 service的方法,大家也许会很奇怪,为什么不做到action而是service,哎,这个没法子,我们前台用的是flex,而flex调用 java跟rpc很像,就是flex直接调用service的方法,因此控制层在前台,和前台的耦合度太高,只得做service方法级别的拦截了。
我是按下面顺序开发的:
1.先看看我新的目录结构
还要加入三个jar包,都是AspectJ相关的,如下图:
2.在cn.com.sharpxiajun.service包下新建接口UsersService,代码如下:
import java.util.List;
import java.util.Map;
public interface UsersService {
public List<Map<String,Object>> queryUsersList(Map<String, Object> map) throws Exception;
}
3.实现UsersService接口,在cn.com.sharpxiajun.service.impl包下面新建类UsersServiceImpl,代码如下:
package cn.com.sharpxiajun.service.impl;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import cn.com.sharpxiajun.dao.UsersDao;
import cn.com.sharpxiajun.service.UsersService;
@SuppressWarnings("unchecked")
@Scope("prototype")
@Service("userService")
public class UsersServiceImpl implements UsersService {
@Autowired
@Qualifier("usersDao")
private UsersDao usersDao =null;
@Override
public List<Map<String,Object>> queryUsersList(Map<String, Object> map)
throws Exception {
returnusersDao.queryUserList(map);
}
}package cn.com.sharpxiajun.service.impl;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import cn.com.sharpxiajun.dao.UsersDao;
import cn.com.sharpxiajun.service.UsersService;
@SuppressWarnings("unchecked")
@Scope("prototype")
@Service("userService")
public class UsersServiceImpl implements UsersService {
@Autowired
@Qualifier("usersDao")
private UsersDao usersDao =null;
@Override
public List<Map<String,Object>> queryUsersList(Map<String, Object> map)
throws Exception {
returnusersDao.queryUserList(map);
}
}
大家可以看到service注解是@service,其他和dao差不多(我感觉要写篇文章好好介绍下spring相关注解,只有这样才能对框架有深刻理解)
4.接下来编写方法拦截器,这个类放在cn.com.sharpxiajun.common.aop包下,类名是:
MethodServiceAdvisor,代码如下:
package cn.com.sharpxiajun.common.aop;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import cn.com.sharpxiajun.service.UsersService;
public class MethodServiceAdvisor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocationinvocation) throws Throwable {
Object obj = null;
System.out.println("进入到了方法拦截器。。。。");
System.out.println("调用的service:");
System.out.println(invocation.getThis());
System.out.println("调用的方法:");
System.out.println(invocation.getMethod());
System.out.println("参数是:");
for (int i = 0;i <invocation.getArguments().length;i++)
{
Object[] objs =invocation.getArguments();
System.out.println(objs[i]);
}
obj =invocation.proceed();
System.out.println("返回结果是:");
System.out.println(obj);
System.out.println("拦截器执行结束!!");
return obj;
}
}
拦截器的注解我今天不写,太晚了,而且记得不清,下一篇里我会补上这些内容。
5.下面是修改后的applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx-2.0.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- 扫描该路径下的spring组件 -->
<context:component-scanbase-package="cn.com.sharpxiajun"/>
<!-- 读取资源文件 -->
<beanid="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<propertyname="locations">
<list>
<value>classpath:conf/constants.properties</value>
</list>
</property>
</bean>
<!-- 配置数据源 -->
<!-- <bean id="myDataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource">
<propertyname="driverClass" value="${db.driverClass}"/>
<property name="jdbcUrl"value="${db.jdbcUrl}"/>
<propertyname="user" value="${db.user}"/>
<propertyname="password" value="${db.password}"/>
</bean>-->
<beanid="myDataSource"class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close">
<propertyname="driverClassName" value="${db.driverClass}"/>
<propertyname="url" value="${db.jdbcUrl}"/>
<propertyname="username" value="${db.user}"/>
<propertyname="password" value="${db.password}"/>
</bean>
<beanid="sqlMapClient"class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<propertyname="configLocation">
<value>classpath:conf/SqlMapConfig.xml</value>
</property>
<propertyname="dataSource" ref="myDataSource"/>
</bean>
<beanid="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<propertyname="sqlMapClient">
<reflocal="sqlMapClient"/>
</property>
</bean>
<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource">
<reflocal="myDataSource"/>
</property>
</bean>
<!-- 将我自己定义的拦截器生成bean -->
<beanid="methodServiceAdvisor"class="cn.com.sharpxiajun.common.aop.MethodServiceAdvisor"/>
<aop:config>
<!--配置规则,满足以下规则的将拦截,第一个*表示所有返回类型,第二个表示service包下的所有class,第三个表示所有方法-->
<aop:pointcutid="baseServiceMethods" expression="execution(*cn.com.sharpxiajun.service.*.*(..))"/>
<!-- 符合上面规则的拦截器都会调用到methodServiceAdvisor-->
<aop:advisoradvice-ref="methodServiceAdvisor"pointcut-ref="baseServiceMethods"/>
</aop:config>
</beans>
这里用到了aop:config这是spring为了迎合AspectJ,对于AspectJ这个以后有机会我也想研究下,写篇文章。
6.最后编写针对UsersService的测试类UsersServiceImplTest,所在包是:cn.com.sharpxiajun.junittest.service,代码如下:
package cn.com.sharpxiajun.junittest.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
importorg.springframework.test.context.transaction.TransactionConfiguration;
import cn.com.sharpxiajun.service.UsersService;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:conf/applicationContext.xml"})
@TransactionConfiguration(defaultRollback = false)
public class UsersServiceImplTest extends
AbstractTransactionalJUnit4SpringContextTests {
@Autowired
private UsersServiceusersService = null;
public UsersServiceImplTest()
{
System.out.println("初始化测试类....");
}
@Before
public void setUp() throwsException
{
System.out.println("测试开始....");
}
@After
public void tearDown() throwsException
{
System.out.println("测试结束!!");
}
@Test
public voidtestQueryUserList()
{
Map<String, Object>map = new HashMap<String, Object>();
map.put("username", "sharpxiajun");
try {
List<Map<String, Object>> list =usersService.queryUsersList(map);
System.out.println(list);
} catch (Exception e) {
// TODOAuto-generated catch block
e.printStackTrace();
}
}
}
运行结果如下:
初始化测试类....
2011-10-11 23:44:45org.springframework.beans.factory.xml.XmlBeanDefinitionReaderloadBeanDefinitions
信息: Loading XML bean definitions from class path resource[conf/applicationContext.xml]
2011-10-11 23:44:45org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshingorg.springframework.context.support.GenericApplicationContext@290fbc: startupdate [Tue Oct 11 23:44:45 CST 2011]; root of context hierarchy
2011-10-11 23:44:46org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
信息: Loading properties file from class path resource[conf/constants.properties]
2011-10-11 23:44:46org.springframework.beans.factory.support.DefaultListableBeanFactorypreInstantiateSingletons
信息: Pre-instantiating singletons inorg.springframework.beans.factory.support.DefaultListableBeanFactory@922804:defining beans [usersDao,userService,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,propertyConfigurer,myDataSource,sqlMapClient,sqlMapClientTemplate,transactionManager,methodServiceAdvisor,org.springframework.aop.config.internalAutoProxyCreator,baseServiceMethods,org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0];root of factory hierarchy
2011-10-11 23:44:46org.springframework.test.context.transaction.TransactionalTestExecutionListenerstartNewTransaction
信息: Began transaction (1): transaction manager[org.springframework.jdbc.datasource.DataSourceTransactionManager@8de972];rollback [false]
测试开始....
进入到了方法拦截器。。。。
调用的service:
cn.com.sharpxiajun.service.impl.UsersServiceImpl@15fc672
调用的方法:
public abstract java.util.Listcn.com.sharpxiajun.service.UsersService.queryUsersList(java.util.Map) throwsjava.lang.Exception
参数是:
{username=sharpxiajun}
返回结果是:
[{enabled=false, username=admin,password=admin}, {enabled=false, username=test, password=test}]
拦截器执行结束!!
[{enabled=false, username=admin,password=admin}, {enabled=false, username=test, password=test}]
测试结束!!
2011-10-11 23:44:46org.springframework.test.context.transaction.TransactionalTestExecutionListenerendTransaction
信息: Committed transaction after test execution for test context[[TestContext@58e2a1 testClass = UsersServiceImplTest, locations =array<String>['classpath:conf/applicationContext.xml'], testInstance =cn.com.sharpxiajun.junittest.service.UsersServiceImplTest@186f3b3, testMethod =testQueryUserList@UsersServiceImplTest, testException = [null]]]