軟件151 黃旭 1531610120javascript
今天我將寫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,代碼以下:前端
package cn.com.sharpxiajun.service;
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,代碼以下:java
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 {
return usersDao.queryUserList(map);
}
}
你們能夠看到service註解是@service,其餘和dao差很少(我感受要寫篇文章好好介紹下spring相關注解,只有這樣才能對框架有深入理解)spring
4.接下來編寫方法攔截器,這個類放在cn.com.sharpxiajun.common.aop包下,類名是:MethodServiceAdvisor,代碼以下:sql
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(MethodInvocation invocation) 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;
}
}
攔截器的註解我今天不寫,太晚了,並且記得不清,下一篇裏我會補上這些內容。express
5.下面是修改後的applicationContext.xml配置文件,內容以下:apache
<?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/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.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">
<!-- 掃描該路徑下的spring組件 -->
<context:component-scan base-package="cn.com.sharpxiajun"/>
<!-- 讀取資源文件 -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:conf/constants.properties</value>
</list>
</property>
</bean>
<!-- 配置數據源 -->
<!-- <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${db.driverClass}"/>
<property name="jdbcUrl" value="${db.jdbcUrl}"/>
<property name="user" value="${db.user}"/>
<property name="password" value="${db.password}"/>
</bean>-->
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${db.driverClass}"/>
<property name="url" value="${db.jdbcUrl}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.password}"/>
</bean>
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation">
<value>classpath:conf/SqlMapConfig.xml</value>
</property>
<property name="dataSource" ref="myDataSource"/>
</bean>
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate">
<property name="sqlMapClient">
<ref local="sqlMapClient"/>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource">
<ref local="myDataSource"/>
</property>
</bean>
<!-- 將我本身定義的攔截器生成bean -->
<bean id="methodServiceAdvisor" class="cn.com.sharpxiajun.common.aop.MethodServiceAdvisor"/>
<aop:config>
<!--配置規則,知足如下規則的將攔截,第一個*表示全部返回類型,第二個表示service包下的全部class,第三個表示全部方法-->
<aop:pointcut id="baseServiceMethods" expression="execution(* cn.com.sharpxiajun.service.*.*(..))"/>
<!-- 符合上面規則的攔截器都會調用到methodServiceAdvisor -->
<aop:advisor advice-ref="methodServiceAdvisor" pointcut-ref="baseServiceMethods"/>
</aop:config>
</beans>
這裏用到了aop:config這是spring爲了迎合AspectJ,對於AspectJ這個之後有機會我也想研究下,寫篇文章。app
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;
import org.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 UsersService usersService = null;
public UsersServiceImplTest()
{
System.out.println("初始化測試類....");
}
@Before
public void setUp() throws Exception
{
System.out.println("測試開始....");
}
@After
public void tearDown() throws Exception
{
System.out.println("測試結束!!");
}
@Test
public void testQueryUserList()
{
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) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
運行結果以下:ide
初始化測試類....
2011-10-11 23:44:45 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [conf/applicationContext.xml]
2011-10-11 23:44:45 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.GenericApplicationContext@290fbc: startup date [Tue Oct 11 23:44:45 CST 2011]; root of context hierarchy
2011-10-11 23:44:46 org.springframework.core.io.support.PropertiesLoaderSupport loadProperties
信息: Loading properties file from class path resource [conf/constants.properties]
2011-10-11 23:44:46 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.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:46 org.springframework.test.context.transaction.TransactionalTestExecutionListener startNewTransaction
信息: 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.List cn.com.sharpxiajun.service.UsersService.queryUsersList(java.util.Map) throws java.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:46 org.springframework.test.context.transaction.TransactionalTestExecutionListener endTransaction
信息: 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]]]
看來達到咱們預期的結果了!!!
總結下了:這樣寫程序蠻有成就感,並且一步步來感受很清晰。工做永遠是匆忙的,老是快的讓人沒法思考,我想這就是聰明的中國爲何沒有那麼多優秀開源框架的緣由把。今天我又獲得一個js開源框架,得到源碼,它能作出yfiles同樣的效果,很是強大,也是老外寫的,牛的不行啊,咱們平臺開發原本對前端要求很高的,要求圖形化實現,真正作圖形化才知道他的複雜度之高,之後我會介紹下這個圖形化的框架,他能實現畫圖,自定義工做流,還能爲關係複雜的圖形進行佈局合理的自動繪製,太牛了。
下個階段可能要回歸javascript了,java框架暫停一下。