使用Spring AOP 实现日志管理(简单教程)

有时候,我们在做项目时会遇到这样的需求:

给XXX.java中的所有方法加上指定格式的日志输出。

针对这种指定类、或者指定方法进行共性操作的功能,我们完全可以使用Spring AOP来实现。

本文使用注解方式:

步骤如下:

 1 package com.longti.ydgj.util;
 2 
 3 import java.util.LinkedHashMap;
 4 
 5 
 6 import org.aspectj.lang.JoinPoint;
 7 import org.aspectj.lang.annotation.Aspect;
 8 import org.aspectj.lang.annotation.Before;
 9 import org.aspectj.lang.annotation.Pointcut;
10 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory;
12 
13 
14
@Aspect // 指定当前类为切面类 15 public class MatchLogAspect { 16 17 private static final Logger logger = LoggerFactory.getLogger(MatchLogAspect. class); 18 19 // 指定切入点表单式: 拦截哪些方法; 即为哪些类生成代理对象 20 @Pointcut("execution(* com.longti.ydgj.webservice.impl.MatchWebServiceImpl.*(..))") 21 public void pointCut_1(){ 22 } 23 24 // 前置通知 : 在执行目标方法之前执行 25 @Before("pointCut_1()") 26 public void printLog1(JoinPoint joinPoint){ 27 try{ 28 String methodName=joinPoint.getTarget().getClass()+"."+joinPoint.getSignature().getName() + "()"; 29 logger.info(methodName+"--请求参数开始--->"); 30 if(joinPoint.getArgs().length>0){ 31 for (int i = 0; i < joinPoint.getArgs().length; i++) { 32 LinkedHashMap<String, Object> jsonParam=(LinkedHashMap<String, Object>)joinPoint.getArgs()[i]; 33 if(jsonParam.size()>0){ 34 for(String key:jsonParam.keySet()){ 35 StringBuffer sb=new StringBuffer(); 36 sb.append(key+"--=>"); 37 sb.append(jsonParam.get(key)==null?"":jsonParam.get(key).toString()); 38 logger.info(sb.toString()); 39 } 40 } 41 } 42 } 43 logger.info(methodName+"--请求参数结束--->"); 44 }catch(Exception e){ 45 e.printStackTrace(); 46 } 47 } 48 49 50 51 52 }

 在切面类中定义切入点,以及拦截方法后进行的操作。

设置好了切面类之后,需要在spring配置文件中进行相关aop配置:

1.开启注解扫描:

<context:component-scan base-package="com.longti.ydgj.util" />

2.

<!-- 开启aop注解方式 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

3.

如果切面类没有使用@Component来创建实例的话,则需要在spring配置文件中声明bean

<!--切面-->
<bean id="matchLogAspect" class="com.longti.ydgj.util.MatchLogAspect"></bean>

综上,搞定。


切入点表达式讲解(以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:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">
    
    <!-- dao 实例 -->
    <bean id="userDao" class="cn.itcast.g_pointcut.UserDao"></bean>
    <bean id="orderDao" class="cn.itcast.g_pointcut.OrderDao"></bean>
    
    <!-- 切面类 -->
    <bean id="aop" class="cn.itcast.g_pointcut.Aop"></bean>
    
    <!-- Aop配置 -->
    <aop:config>
        
        <!-- 定义一个切入点表达式: 拦截哪些方法 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.*.*(..))" id="pt"/>-->
        
        <!-- 【拦截所有public方法】 -->
        <!--<aop:pointcut expression="execution(public * *(..))" id="pt"/>-->
        
        <!-- 【拦截所有save开头的方法 】 -->
        <!--<aop:pointcut expression="execution(* save*(..))" id="pt"/>-->
        
        <!-- 【拦截指定类的指定方法, 拦截时候一定要定位到方法】 -->
        <!--<aop:pointcut expression="execution(public * cn.itcast.g_pointcut.OrderDao.save(..))" id="pt"/>-->
        
        <!-- 【拦截指定类的所有方法】 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.*(..))" id="pt"/>-->
        
        <!-- 【拦截指定包,以及其自包下所有类的所有方法】 -->
        <!--<aop:pointcut expression="execution(* cn..*.*(..))" id="pt"/>-->
        
        <!-- 【多个表达式】 -->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) || execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->
        <!--<aop:pointcut expression="execution(* cn.itcast.g_pointcut.UserDao.save()) or execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>-->

        
        <!-- 【取非值】 -->
        <aop:pointcut expression=" not execution(* cn.itcast.g_pointcut.OrderDao.save())" id="pt"/>
        
        <!-- 切面 -->
        <aop:aspect ref="aop">
            <!-- 环绕通知 -->
            <aop:around method="around" pointcut-ref="pt"/>
        </aop:aspect>
    </aop:config>
</beans>    

欢迎讨论。。。


原文地址:https://www.cnblogs.com/zhaojiatao/p/7389542.html