首页 > 代码库 > 在Springmvc的工程中对DAO做切面来评估DAO的方法耗时时间

在Springmvc的工程中对DAO做切面来评估DAO的方法耗时时间

一、Spring的mvc配置以及使用
二、Spring的aop切面配置以及使用
三、Spring的aop切面在spring-mvc中失效的问题
四、通过aop切面来评估所有的dao在执行过程中的耗时

一、Spring的mvc配置以及使用
  a、在pom.xml中引入spring的jar包。
  b、在web.xml中配置,初始化dispatcherServlet,加载WebApplicationContext 容器。

        <!-- 加载Springmvc得拦截器,初始化WebApplicationContext -->
        <servlet>
                <servlet-name>dispatcherServlet</servlet-name>

                <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>
          <param-name>contextConfigLocation</param-name>

          <param-value>classpath:applicationContext-mvc.xml</param-value>

        </init-param>
         <load-on-startup>1</load-on-startup>
 
        </servlet>

        <servlet-mapping>                <servlet-name>dispatcherServlet</servlet-name>                <url-pattern>*.action</url-pattern>        </servlet-mapping>
 c、在applicationContext-mvc.xml中配置视图解析器以及注解配置
        <!-- SpringMVC: 配置自动扫描的包 和 ViewResolver -->

        <context:component-scan base-package="com.dhpei"></context:component-scan>
 
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
            <property name="viewClass" value="http://www.mamicode.com/org.springframework.web.servlet.view.JstlView"/>  
            <property name="prefix" value="http://www.mamicode.com/WEB-INF/jsp/"/>  
            <property name="suffix" value="http://www.mamicode.com/.jsp"/>  
        </bean> 
d、注解使用 
@Controller
@RequestMapping("/user")
public class UserController  {  
        @Resource
        private UserDao userDao;
        @Resource
        private SystemParamDao systemParamDao;
        @RequestMapping("/userList")
         public String userList(Model model,HttpServletRequest request,HttpServletResponse response){
                Map<String,String> query=new HashMap<String,String>();
                List<UserEntity> userList=userDao.findUserList(query);
                List<SystemParamRowMapper> sexList=systemParamDao.getSystemParamByCategoryCode("sex");
                model.addAttribute("sexList", sexList);
                model.addAttribute("userList", userList);
                return "user/userList";
         } 
访问:http://localhost:8080/knowledge/user/userList.action 得到访问页面。
 
二、Spring的aop切面配置以及使用
a、在pom.xml中引入spring的aop相关jar包以及aspectjrt和aspectjweaver对应version的jar包。
        <!-- 加载Spring的容器,初始化ApplicationContext -->
        <listener>
                <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
b、在web.xml中配置,加载ApplicationContext 容器。
          <!-- 加载Spring的容器,初始化ApplicationContext -->
        <listener>
                <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <context-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:applicationContext.xml</param-value>
        </context-param>
c、在applicationContext.xml中配置aop切面
            <!-- Spring: 配置自动扫描的包-->
         <context:component-scan base-package="com.dhpei"/>
           <!-- Spring的aop切面管理 -->
          <bean id="logAspect" class="com.dhpei.utils.aop.LogAspect"/>
            <aop:config>  
                <aop:aspect id="aspect" ref="logAspect">  
                   <!--第一个*指任意返回值,第二个*指knowledge下面的任意包,第三个*指impl下面的任意的类,第四个*指任意方法-->
                    <aop:pointcut id="logpointcut" expression="execution(* com.dhpei.knowledge.*.dao.impl.*.*(..))"/>  
                    <aop:around method="traceMethod"  pointcut-ref="logpointcut"/>  
                </aop:aspect>
            </aop:config>
d、切面LogAspect
package com.dhpei.utils.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogAspect {
    //切面方法
    public Object traceMethod(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Object returnVal = null;
        final Logger log = getLog(proceedingJoinPoint);//获取当前执行的dao类的全称
        final String methodName = proceedingJoinPoint.getSignature().getName();//获取当前dao类的执行方法
        long start=System.currentTimeMillis(); 
        try {
            if (log.isInfoEnabled()) {
                final Object[] args = proceedingJoinPoint.getArgs();
                final String arguments;
                if (args == null || args.length == 0) {
                    arguments = "";
                } else {
                    arguments = Arrays.deepToString(args);
                }
                log.info("进入方法 [" + methodName + "];参数 [" + arguments + "]");
            }
            returnVal = proceedingJoinPoint.proceed();
            return returnVal;
        } finally {
            if (log.isInfoEnabled()) {
                log.info("离开方法 [" + methodName + "] ;返回值 [" + (returnVal != null ? returnVal.toString() : "null") + "].");
                long end=System.currentTimeMillis();
                log.info("执行方法耗时:"+(end-start)+"毫秒。");
            }
        }
    }
    protected Logger getLog(final JoinPoint joinPoint) {
        final Object target = joinPoint.getTarget();
        if (target != null) {
            return LoggerFactory.getLogger(target.getClass());
        }
        return LoggerFactory.getLogger(getClass());
    }
}
 
三、Spring的aop切面在spring-mvc中失效的问题
    将第一步和第二步的配置融合到一起使用,会发现aop切面执行不了。经过多方面调查原因,发现是由于Spring的mvc(WebApplicationContext 容器)在加载的过程中已经对dao对应的类做了扫描加载到容器中,当spring本身的(ApplicationContext 容器)再去扫描的时候发现已经加载到内存中,从而跳过了AOP的切面增强。
   修改applicationContext-mvc.xml,添加excloud配置
         <!-- SpringMVC: 配置自动扫描的包 和 ViewResolver -->
         <context:component-scan base-package="com.dhpei">
                 <!-- 在Controller这一层加AOP增强 -->
                 <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
         </context:component-scan>
   修改之后再启动工程,就可以正确的看到AOP的切面效果了。
 
四、通过aop切面来评估所有的dao在执行过程中的耗时
启动aop的切面之后,再次访问http://localhost:8080/knowledge/user/userList.action,可以看到debug日志如下:
2016.11.15 12:50:40 DEBUG CommonUtils - serviceUrl generated: http://localhost:8080/knowledge/user/userList.action
2016.11.15 12:50:40 DEBUG DispatcherServlet - DispatcherServlet with name ‘dispatcherServlet‘ processing GET request for [/knowledge/user/userList.action]
2016.11.15 12:50:40 DEBUG DefaultAnnotationHandlerMapping - Matching patterns for request [/user/userList.action] are [/user/userList.*]
2016.11.15 12:50:40 DEBUG DefaultAnnotationHandlerMapping - URI Template variables for request [/user/userList.action] are {}
2016.11.15 12:50:40 DEBUG DefaultAnnotationHandlerMapping - Mapping [/user/userList.action] to HandlerExecutionChain with handler [com.dhpei.knowledge.user.controller.UserController@10ad85e] and 1 interceptor
2016.11.15 12:50:40 DEBUG DispatcherServlet - Last-Modified value for [/knowledge/user/userList.action] is: -1
2016.11.15 12:50:40 DEBUG HandlerMethodInvoker - Invoking request handler method: public java.lang.String com.dhpei.knowledge.user.controller.UserController.userList(org.springframework.ui.Model,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2016.11.15 12:50:40 DEBUG AnnotationTransactionAttributeSource - Adding transactional method ‘UserDaoImpl.findUserList‘ with attribute: PROPAGATION_NOT_SUPPORTED,ISOLATION_DEFAULT,readOnly; ‘‘
2016.11.15 12:50:40 DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean ‘txManager‘
2016.11.15 12:50:40 DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean ‘logAspect‘
2016.11.15 12:50:40 INFO  UserDaoImpl - 进入方法 [findUserList];参数 [[{}]]
2016.11.15 12:50:40 DEBUG -UserDaoImpl- - execurte sql: select * from ts_user 
2016.11.15 12:50:40 DEBUG JdbcTemplate - Executing SQL query [ select * from ts_user ]
2016.11.15 12:50:40 DEBUG DataSourceUtils - Fetching JDBC Connection from DataSource
2016.11.15 12:50:40 DEBUG DataSourceUtils - Registering transaction synchronization for JDBC Connection
2016.11.15 12:50:40 INFO  UserDaoImpl - 离开方法 [findUserList] ;返回值 [[UserEntity [id=1, userName=林肯, loginName=liken, password=670b14728ad9902aecba32e22fa4f6bd], UserEntity [id=2, userName=马克, loginName=make, password=32e22fa4f6bd670b14728ad9902aecba], UserEntity [id=3, userName=德克, loginName=deke, password=8ad9902aecba32e22670b1472fa4f6bd], UserEntity [id=4, userName=科林, loginName=kelin, password=70b14728ad9902aecba32e22fa4f6bd6]]].
2016.11.15 12:50:40 INFO  UserDaoImpl - 执行方法耗时:20毫秒。
2016.11.15 12:50:40 DEBUG DataSourceUtils - Returning JDBC Connection to DataSource
2016.11.15 12:50:40 DEBUG DefaultListableBeanFactory - Returning cached instance of singleton bean ‘logAspect‘
2016.11.15 12:50:40 INFO  SystemParamDaoImpl - 进入方法 [getSystemParamByCategoryCode];参数 [[sex]]
2016.11.15 12:50:40 DEBUG -SystemParamDaoImpl- - syp from db!
2016.11.15 12:50:40 DEBUG JdbcTemplate - Executing prepared SQL query
2016.11.15 12:50:40 DEBUG JdbcTemplate - Executing prepared SQL statement [ select type_code,type_name from ts_system_param where category_code=? ]
2016.11.15 12:50:40 DEBUG DataSourceUtils - Fetching JDBC Connection from DataSource
2016.11.15 12:50:40 DEBUG PreparedStatementPool - {conn-10001, pstmt-20001} enter cache
2016.11.15 12:50:40 DEBUG DataSourceUtils - Returning JDBC Connection to DataSource
2016.11.15 12:50:40 DEBUG -SystemParamDaoImpl- - category_code:scode;result:[SystemParamEntity [typeCode=0, typeName=男], SystemParamEntity [typeCode=1, typeName=女]]
2016.11.15 12:50:40 INFO  SystemParamDaoImpl - 离开方法 [getSystemParamByCategoryCode] ;返回值 [[SystemParamEntity [typeCode=0, typeName=男], SystemParamEntity [typeCode=1, typeName=女]]].
2016.11.15 12:50:40 INFO  SystemParamDaoImpl - 执行方法耗时:20毫秒。
2016.11.15 12:50:40 DEBUG Segment - put added 0 on heap
2016.11.15 12:50:40 DEBUG DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name ‘user/userList‘
2016.11.15 12:50:40 DEBUG DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name ‘user/userList‘; URL [/WEB-INF/jsp/user/userList.jsp]] in DispatcherServlet with name ‘dispatcherServlet‘
2016.11.15 12:50:40 DEBUG JstlView - Added model object ‘sexList‘ of type [java.util.ArrayList] to request in view with name ‘user/userList‘
2016.11.15 12:50:40 DEBUG JstlView - Added model object ‘userList‘ of type [java.util.ArrayList] to request in view with name ‘user/userList‘
2016.11.15 12:50:40 DEBUG Segment - fault removed 0 from heap
2016.11.15 12:50:40 DEBUG Segment - fault added 0 on disk
2016.11.15 12:50:40 DEBUG JstlView - Forwarding to resource [/WEB-INF/jsp/user/userList.jsp] in InternalResourceView ‘user/userList‘
2016.11.15 12:50:41 DEBUG DispatcherServlet - Successfully completed request
 
 



在Springmvc的工程中对DAO做切面来评估DAO的方法耗时时间