aop拦截service&&controller《一》

来源:互联网 发布:怎样可以联系淘宝店主 编辑:程序博客网 时间:2024/06/05 09:01

利用自定义注释完成对controller和service的拦截

1.自定义拦截注释

1).SystemControllerLog  拦截controller注解类

package com.fuliwd.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *自定义注解 拦截Controller
 */ 
@Target({ElementType.PARAMETER, ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
public  @interface SystemControllerLog { 
    String description()  default ""; 
}

2).SystemServiceLog 拦截service注解类

package com.fuliwd.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 *自定义注解 拦截service
 */ 
@Target({ElementType.PARAMETER, ElementType.METHOD}) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
public  @interface SystemServiceLog { 
    String description()  default ""; 
}

2.修改springmvc配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd 
                        http://www.springframework.org/schema/mvc 
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
                         http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd ">
 <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
 <context:component-scan base-package="com.fuliwd.controler" />
 <!--避免IE执行AJAX时,返回JSON出现下载文件 -->
 <bean id="mappingJacksonHttpMessageConverter"
  class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
  <property name="supportedMediaTypes">
   <list>
    <value>text/html;charset=UTF-8</value>
   </list>
  </property>
 </bean>
 <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->
 <bean
  class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="messageConverters">
   <list>
    <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->
   </list>
  </property>
 </bean>
 <!-- 定义跳转的文件的前后缀 ,视图模式配置-->
 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <!-- 这里的配置我的理解是自动给后面action的方法return的字符串加上前缀和后缀,变成一个 可用的url地址 -->
  <property name="prefix" value="/WEB-INF/jsp/" />
  <property name="suffix" value=".jsp" />
 </bean>
 
 
     


<!-- <mvc:annotation-driven /> -->
     <!-- 激活组件扫描功能,在包com.gcx及其子包下面自动扫描通过注解配置的组件 -->
     <context:component-scan base-package="com.fuliwd" />
 <!--  <context:component-scan base-package="com.fuliwd.service" />
  <context:component-scan base-package="com.fuliwd.annotation" /> -->
  

     <!-- 启动对@AspectJ注解的支持 -->
     <!-- proxy-target-class等于true是强制使用cglib代理,proxy-target-class默认是false,如果你的类实现了接口 就走JDK代理,如果没有,走cglib代理  -->
     <!-- 注:对于单利模式建议使用cglib代理,虽然JDK动态代理比cglib代理速度快,但性能不如cglib -->

     <!--如果不写proxy-target-class="true"这句话也没问题-->
     <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 
     <aop:aspectj-autoproxy proxy-target-class="true" />
     <!--切面-->
     <bean id="systemLogAspect" class="com.fuliwd.annotation.SystemLogAspect"></bean>

</beans>

3.创建切点类

package com.fuliwd.annotation;


import java.lang.reflect.Method;
import java.util.Date;
import java.util.UUID;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.fuliwd.pojo.SystemLog;
import com.fuliwd.pojo.User;

@Aspect
@Component
public class SystemLogAspect {
 //注入Service用于把日志保存数据库   
     /* @Resource   
       private LogService logService;    */
      //本地异常日志记录对象   
       private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);   
     
      //Service层切点   
      @Pointcut("@annotation(com.fuliwd.annotation.SystemServiceLog)")   
       public  void serviceAspect() {  
       System.out.println("service切面");
      }   
     
      //Controller层切点   
      @Pointcut("@annotation(com.fuliwd.annotation.SystemControllerLog)")   
       public  void controllerAspect() {   
       System.out.println("controller切面");
      }   
     
      /**
       * 前置通知 用于拦截Controller层记录用户的操作
       *
       * @param joinPoint 切点
       */
//      @Before("controllerAspect()")
//      @Before("serviceAspect() || controllerAspect()")
      @Before("execution(* com.fuliwd.controller..*.*(..))")
      public void doBefore(JoinPoint joinPoint) {
          System.out.println("==========执行controller前置通知===============");
          if(logger.isInfoEnabled()){
              logger.info("before " + joinPoint);
          }
      }   
     
      //配置controller环绕通知,使用在方法aspect()上注册的切入点
//        @Around("controllerAspect()")
        @Around("serviceAspect()")
        public void around(JoinPoint joinPoint){
            System.out.println("==========开始执行controller环绕通知===============");
            long start = System.currentTimeMillis();
            try {
                ((ProceedingJoinPoint) joinPoint).proceed();
                long end = System.currentTimeMillis();
                if(logger.isInfoEnabled()){
                    logger.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms!");
                }
                System.out.println("==========结束执行controller环绕通知===============");
            } catch (Throwable e) {
                long end = System.currentTimeMillis();
                if(logger.isInfoEnabled()){
                    logger.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage());
                }
            }
        }
     
      /**
       * 后置通知 用于拦截Controller层记录用户的操作
       *
       * @param joinPoint 切点
       */ 
//      @After("controllerAspect()") 
      @After("serviceAspect()")
      public  void after(JoinPoint joinPoint) { 
   
         /* HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 
          HttpSession session = request.getSession();  */
          //读取session中的用户 
         // User user = (User) session.getAttribute("user"); 
          //请求的IP 
          //String ip = request.getRemoteAddr();
          User user = new User();
          user.setId(1);
          user.setUserName("张三");
          String ip = "127.0.0.1";
           try { 
             
              String targetName = joinPoint.getTarget().getClass().getName(); 
              String methodName = joinPoint.getSignature().getName(); 
              Object[] arguments = joinPoint.getArgs(); 
              Class targetClass = Class.forName(targetName); 
              Method[] methods = targetClass.getMethods();
              String operationType = "";
              String operationName = "";
              /* for (Method method : methods) { 
                   if (method.getName().equals(methodName)) { 
                      Class[] clazzs = method.getParameterTypes(); 
                       if (clazzs.length == arguments.length) { 
                           operationType = method.getAnnotation(Log.class).operationType();
                           operationName = method.getAnnotation(Log.class).operationName();
                           break; 
                      } 
                  } 
              }*/
              //*========控制台输出=========*// 
              System.out.println("=====controller后置通知开始====="); 
              System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType); 
              System.out.println("方法描述:" + operationName); 
              System.out.println("请求人:" + user.getUserName()); 
              System.out.println("请求IP:" + ip); 
              //*========数据库日志=========*// 
             /* SystemLog log = new SystemLog(); 
              log.setId(UUID.randomUUID().toString());
              log.setDescription(operationName); 
              log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType); 
              log.setLogType((long)0); 
              log.setRequestIp(ip); 
              log.setExceptioncode( null); 
              log.setExceptionDetail( null); 
              log.setParams( null); 
              log.setCreateBy(user.getUserName()); 
              log.setCreateDate(new Date()+""); 
              //保存数据库 
              systemLogService.insert(log);  */
              System.out.println("=====controller后置通知结束====="); 
          }  catch (Exception e) { 
              //记录本地异常日志 
              logger.error("==后置通知异常=="); 
              logger.error("异常信息:{}", e.getMessage()); 
          } 
      }
     
      //配置后置返回通知,使用在方法aspect()上注册的切入点
//        @AfterReturning("controllerAspect()")
        @AfterReturning("serviceAspect()")
        public void afterReturn(JoinPoint joinPoint){
            System.out.println("=====执行controller后置返回通知====="); 
                if(logger.isInfoEnabled()){
                    logger.info("afterReturn " + joinPoint);
                }
        }
     
      /**
       * 异常通知 用于拦截记录异常日志
       *
       * @param joinPoint
       * @param e
       */ 
       @AfterThrowing(pointcut = "serviceAspect()", throwing="e") 
       public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) { 
          /*HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); 
          HttpSession session = request.getSession(); 
          //读取session中的用户 
          User user = (User) session.getAttribute(WebConstants.CURRENT_USER); 
          //获取请求ip 
          String ip = request.getRemoteAddr(); */
          //获取用户请求方法的参数并序列化为JSON格式字符串 
         
          User user = new User();
          user.setId(1);
          user.setUserName("张三");
          String ip = "127.0.0.1";
         
          String params = ""; 
           if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) { 
               for ( int i = 0; i < joinPoint.getArgs().length; i++) { 
                 /* params += JSONUtil.getJsonStr(joinPoint.getArgs()[i]) + ";";*/ 
              } 
          } 
           try { 
              
               String targetName = joinPoint.getTarget().getClass().getName(); 
               String methodName = joinPoint.getSignature().getName(); 
               Object[] arguments = joinPoint.getArgs(); 
               Class targetClass = Class.forName(targetName); 
               Method[] methods = targetClass.getMethods();
               String operationType = "";
               String operationName = "";
                for (Method method : methods) { 
                    if (method.getName().equals(methodName)) { 
                       Class[] clazzs = method.getParameterTypes(); 
                        if (clazzs.length == arguments.length) { 
                            operationType = method.getAnnotation(Log.class).operationType();
                            operationName = method.getAnnotation(Log.class).operationName();
                            break; 
                       } 
                   } 
               }
               /*========控制台输出=========*/ 
              System.out.println("=====异常通知开始====="); 
              System.out.println("异常代码:" + e.getClass().getName()); 
              System.out.println("异常信息:" + e.getMessage()); 
              System.out.println("异常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")+"."+operationType); 
              System.out.println("方法描述:" + operationName); 
              System.out.println("请求人:" + user.getUserName()); 
              System.out.println("请求IP:" + ip); 
              System.out.println("请求参数:" + params); 
                 /*==========数据库日志=========*/ 
            /*  SystemLog log = new SystemLog();
              log.setId(UUID.randomUUID().toString());
              log.setDescription(operationName); 
              log.setExceptioncode(e.getClass().getName()); 
              log.setLogType((long)1); 
              log.setExceptionDetail(e.getMessage()); 
              log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")); 
              log.setParams(params); 
              log.setCreateBy(user.getUserName()); 
              log.setCreateDate(new Date()+""); 
              log.setRequestIp(ip); 
              //保存数据库 
              systemLogService.insert(log);  */
              System.out.println("=====异常通知结束====="); 
          }  catch (Exception ex) { 
              //记录本地异常日志 
              logger.error("==异常通知异常=="); 
              logger.error("异常信息:{}", ex.getMessage()); 
          } 
           /*==========记录本地异常日志==========*/ 
          logger.error("异常方法:{}异常代码:{}异常信息:{}参数:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params); 
   
      }    

}

4.使用

1)controller

package com.fuliwd.controler;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.fuliwd.annotation.Log;
import com.fuliwd.annotation.SystemControllerLog;
import com.fuliwd.pojo.User;
import com.fuliwd.service.IUserService;

@Controller
@RequestMapping("/user")
public class UserController {
 @Resource
 private IUserService userService;
 
 @RequestMapping("/showUser")
 @SystemControllerLog(description = "controller拦截")
 public String toIndex(String id,HttpServletRequest request,Model model){
  System.out.println("This is controller");
  int userId = Integer.parseInt("1"/*request.getParameter("id")*/);
  User user = this.userService.getUserById(userId);
  model.addAttribute("user", user);
  System.out.println(userId);
  
  return "showUser";
 }
}

2)service

package com.fuliwd.service.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.fuliwd.annotation.SystemServiceLog;
import com.fuliwd.dao.UserMapper;
import com.fuliwd.pojo.User;
import com.fuliwd.service.IUserService;

@Service("userService")
public class UserServiceImpl  implements IUserService{
 
 @Resource
 private UserMapper userMapper;
 @SystemServiceLog(description = "service拦截") 
 public User getUserById(int userId) {
  // TODO Auto-generated method stub
//  return this.userMapper.selectByPrimaryKey(userId);
  System.out.println("This is  service");
  return null;
 }

}


原创粉丝点击