Spring aop切面做日志处理操作

Spring aop切面做日志处理操作有两种方式:

一:通过aop拦截器进行。该拦截器只能单个对业务类进行配置。

在spring配置文件中配置:

<bean id="beforeAdvice" class="com.test.tms.aop.BeforeAdvice"></bean>
<bean id="afterAdvice" class="com.test.tms.aop.AfterAdvice"></bean>
<bean id="compareInterceptor" class="com.test.tms.aop.CompareInterceptor"></bean>
<bean id="studenttarget" class="com.test.tms.aop.StudentImpl"></bean>


<bean id="student" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.test.tms.aop.IStudent</value>
</property>
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
<value>afterAdvice</value>
<value>compareInterceptor</value>
</list>
</property>
<property name="target">
<ref bean="studenttarget" />
</property>


</bean> 

然后创建业务接口IStudent和业务实现类StudentImpl。并创建相关Advice,如BeforeAdvice、AfterAdvice、CompareInterceptor。

最后编写测试类:

public class Test {


    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
      ApplicationContext ctx = 
          new FileSystemXmlApplicationContext("/applicationContext.xml");
      
      IStudent person = (IStudent)ctx.getBean("student");
      person.addStudent("dragon"); 
    }

}


二、通过aop注解实现spring mvc切面日志处理。注意:我们在处理cottroller类进行aop切面时,在poincut需要写上execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))。因为你controller注解的类,都被这个org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter给代理了。


我们通过aspectj进行aop处理。需要在我们项目中导入2个jar包。aspectjrt.jar和aspectjweaver.jar。

在配置文件applicationContext-mvc.xml中增加对aspectj注解的启动等。如下:

<!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- aop -->
<bean id="logService" class="com.test.tms.common.aop.LogService"></bean>


接下来建立切面类.

package com.test.tms.common.aop;
import javax.servlet.http.HttpServletRequest;


import java.lang.reflect.Method; 


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
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.springframework.stereotype.Component;


import com.test.tms.common.annotation.MethodLog;
  
/** 
 * @author LiuKe 
 * @version 1.0 2013-10-21 
 * @show 日志切面 
 */  
@Component
@Aspect
public class LogService{  
  
@Pointcut("@annotation(com.test.tms.common.annotation.MethodLog)")   
    public void log(){}  
      
    @Before("log()")  
    public void LogRequest(JoinPoint joinPoint)  
    {  
        Object obj[] = joinPoint.getArgs();  
          for(Object o :obj){  
           System.out.println("----------------"+o+"----------------");  
          }  
//        System.out.println("========checkSecurity=="+joinPoint.getSignature().getName());//这个是获得方法名   
//      System.out.println("记录了一个请求");   
    }  
      
    @After("log()")  
    public void LogResponse(JoinPoint joinPoint)  
    {  
    }  
    @AfterThrowing("log()")  
    public void LogThrowing(JoinPoint joinPoint)  
    {  
    }  
    
    @Around("log()")   
    public Object around(ProceedingJoinPoint point) throws Throwable {   
        
        String loginName;   
        String name;   
       
  
        String monthRemark = getMthodRemark(point);   
        String monthName = point.getSignature().getName();   
        String packages = point.getThis().getClass().getName();   
        if (packages.indexOf("$$EnhancerByCGLIB$$") > -1) { // 如果是CGLIB动态生成的类   
            try {   
                packages = packages.substring(0, packages.indexOf("$$"));   
            } catch (Exception ex) {   
                ex.printStackTrace();   
            }   
        }   
  
        String operatingcontent = "";   
        Object[] method_param = null;   
  
        Object object;   
        try {   
            method_param = point.getArgs(); //获取方法参数    
            // String param=(String) point.proceed(point.getArgs());   
            object = point.proceed();   
        } catch (Exception e) {   
            // 异常处理记录日志..log.error(e);   
            throw e;   
        }   
        
        //这里有点纠结 就是不好判断第一个object元素的类型 只好通过  方法描述来 做一一  转型感觉 这里 有点麻烦 可能是我对 aop不太了解  希望懂的高手在回复评论里给予我指点   
        //有没有更好的办法来记录操作参数  因为参数会有 实体类 或者javabean这种参数怎么把它里面的数据都解析出来?   
        if ((monthRemark).equals("新增域")) {   
            
          System.out.println("新增域=============================");  
        } else {   
         System.out.println("新增域2222=============================");  
        }   
  
      
        return object;   
    }   
    
 // 获取方法的中文备注____用于记录用户的操作日志描述   
    public static String getMthodRemark(ProceedingJoinPoint joinPoint)   
            throws Exception {   
        String targetName = joinPoint.getTarget().getClass().getName();   
        String methodName = joinPoint.getSignature().getName();   
        Object[] arguments = joinPoint.getArgs();   
  
        Class targetClass = Class.forName(targetName);   
        Method[] method = targetClass.getMethods();   
        String methode = "";   
        for (Method m : method) {   
            if (m.getName().equals(methodName)) {   
                Class[] tmpCs = m.getParameterTypes();   
                if (tmpCs.length == arguments.length) {   
                    MethodLog methodCache = m.getAnnotation(MethodLog.class);   
                    if (methodCache != null) {   
                        methode = methodCache.remark();   
                    }   
                    break;   
                }   
            }   
        }   
        return methode;   
    }   




}  

接下来建立元注解。

package com.test.tms.common.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;   
  
/**  
 * 表示对标记有xxx注解的类,做代理 注解@Retention可以用来修饰注解,是注解的注解,称为元注解。  
 * Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型,  
 * 这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配  
 * RententionPolicy使用。RetentionPolicy有3个值:CLASS RUNTIME SOURCE  
 * 用@Retention(RetentionPolicy  
 * .CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候;  
 * 用@Retention(RetentionPolicy.SOURCE  
 * )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中;  
 * 用@Retention(RetentionPolicy.RUNTIME  
 * )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时,  
 * 所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME  
 * 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用.  
 *   
 * 类和方法的annotation缺省情况下是不出现在javadoc中的,为了加入这个性质我们用@Documented  
 *  java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。  
 *  @interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字   
 *   
 * @author q  
 *   
 */  
  
@Target({ ElementType.METHOD, ElementType.TYPE })   
@Retention(RetentionPolicy.RUNTIME)   
@Documented  
public @interface MethodLog {   
String remark() default "";   
    String operType() default "0";      
   // String desc() default "";   
}  

最后在业务类的方法上增加元注解。

package com.test.tms.domain.controller;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;


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


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;



/**
 * 域控制层
 * 
 * 
 */
@Controller
@RequestMapping("domain")
@SessionAttributes("userInfo")
public class DomainController extends BaseController {


@Resource(name = "domainServiceImpl")
private IDomainService domainService;


/**
* 新增域

* @param domainDO
* @param request
* @return
* @throws ParseException
*/
@RequestMapping("/addDomain")
@MethodLog(remark = "新增域")
public String addDomain(DomainDO domainDO, HttpServletRequest request)
throws ParseException {
String tokenTypeArray = request.getParameter("tokenTypeArray");
String entityTpltArray = request.getParameter("entityTpltArray");
java.text.SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
java.util.Date dateInstance = df.parse("2014/10/27");
domainDO.setTokenType(tokenTypeArray);
domainDO.setEntityTplt(entityTpltArray);
domainDO.setCreateTime(dateInstance);
domainDO.setLastUpdate(11111L);
domainService.save(domainDO);
return "redirect:/domain/getDomainList.jhtml";


}


}


至此就完成了spring mvc 对controller控制层的aop日志操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值