AOP切面詳解


一、spring-aop.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:tx="http://www.springframework.org/schema/tx"
    xmlns:task="http://www.springframework.org/schema/task" 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/tx http://www.springframework.org/schema/tx/spring-tx.xsd
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.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-3.1.xsd   ">
    <!-- 啟動@AspectJ支持 -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
    <context:component-scan base-package="hongmoshui.com.cnblogs.www.base.aop" />
</beans>

二、spring-mybatis.xml文件和spring-mvc.xml文件中,分別導入spring-aop.xml的配置

spring-mybatis.xml【service和dao層的注解有效】:

<?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: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"> <!--讀取jdbc資源文件 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <!-- 允許JVM參數覆蓋 --> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <!-- 忽略沒有找到的資源文件 --> <property name="ignoreResourceNotFound" value="true" /> <!-- 配置資源文件 --> <property name="locations"> <list> <value>classpath:properties/jdbc.properties</value> </list> </property> </bean> <!-- 配置數據源 --> <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> <!-- 數據庫驅動 --> <property name="driverClass" value="${master.jdbc.driver}" /> <!-- 相應驅動的jdbcUrl --> <property name="jdbcUrl" value="${master.jdbc.url}" /> <!-- 數據庫的用戶名 --> <property name="username" value="${master.jdbc.username}" /> <!-- 數據庫的密碼 --> <property name="password" value="${master.jdbc.password}" /> <!-- 檢查數據庫連接池中空閑連接的間隔時間,單位是分,默認值:240,如果要取消則設置為0 --> <property name="idleConnectionTestPeriod" value="60" /> <!-- 連接池中未使用的鏈接最大存活時間,單位是分,默認值:60,如果要永遠存活設置為0 --> <property name="idleMaxAge" value="30" /> <!-- 每個分區最大的連接數 --> <!-- 判斷依據:請求並發數 --> <property name="maxConnectionsPerPartition" value="100" /> <!-- 每個分區最小的連接數 --> <property name="minConnectionsPerPartition" value="5" /> </bean> <!-- 掃描包 --> <context:component-scan base-package="hongmoshui.com.cnblogs.www.*.service.impl,hongmoshui.com.cnblogs.www.*.dao.impl" /> <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自動掃描mapping.xml文件 --> <property name="mapperLocations" value="classpath:mappers*/*Mapper.xml"></property> </bean> <!-- DAO接口所在包名,Spring會自動查找其下的類 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="hongmoshui.com.cnblogs.www.base.dao.impl,hongmoshui.com.cnblogs.www.work.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> <!-- 定義事務管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 導入aop配置 --> <import resource="classpath*:/spring/spring-aop.xml" /> </beans>

spring-mvc.xml【controller層的注解有效】:

<?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:mvc="http://www.springframework.org/schema/mvc" 
    xmlns:aop="http://www.springframework.org/schema/aop"
    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-3.1.xsd   ">  
    
    <!-- 配置注解驅動 -->
    <mvc:annotation-driven/>
    
    <!-- 掃描controller包 -->
    <context:component-scan base-package="hongmoshui.com.cnblogs.www.*.controller"/>
    
    <!-- 配置視圖解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 對靜態資源文件的訪問 ,不支持訪問WEB-INF目錄 --> 
    <!-- <mvc:default-servlet-handler/> -->
    <!-- 對靜態資源文件的訪問 ,可以訪問任何目錄,包括訪問WEB-INF目錄 --> 
    <mvc:resources mapping="/resources/**" location="/resources/" />
    <!-- 導入aop配置 -->
    <import resource="classpath*:/spring/spring-aop.xml" />
</beans>  

 三、自定義注解類【連接點】

package hongmoshui.com.cnblogs.www.work.annotation;

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Log
{
    /**
     * 方法名
     * @author 洪墨水
     */
    public String name() default "";

    /**
     * 描述
     * @author 洪墨水
     */
    public String description() default "no description";
}

參數定義:

@Target 注解

功能:指明了修飾的這個注解的使用范圍,即被描述的注解可以用在哪里。

ElementType的取值包含以下幾種: 

  • TYPE:類,接口或者枚舉

  • FIELD:域,包含枚舉常量

  • METHOD:方法

  • PARAMETER:參數

  • CONSTRUCTOR:構造方法

  • LOCAL_VARIABLE:局部變量

  • ANNOTATION_TYPE:注解類型

  • PACKAGE:包

@Retention 注解

功能:指明修飾的注解的生存周期,即會保留到哪個階段。

RetentionPolicy的取值包含以下三種:

  • SOURCE:源碼級別保留,編譯后即丟棄。

  • CLASS:編譯級別保留,編譯后的class文件中存在,在jvm運行時丟棄,這是默認值。

  • RUNTIME: 運行級別保留,編譯后的class文件中存在,在jvm運行時保留,可以被反射調用。

@Documented 注解

功能:指明修飾的注解,可以被例如javadoc此類的工具文檔化,只負責標記,沒有成員取值。

@Inherited注解

功能:允許子類繼承父類中的注解。

四、自定義切面類

package hongmoshui.com.cnblogs.www.base.aop;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Calendar;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import com.alibaba.fastjson.JSON;

import hongmoshui.com.cnblogs.www.base.utils.TimeUtil;
import hongmoshui.com.cnblogs.www.work.annotation.Log;

/**
 * 日志注解的切面類
 * @author 洪墨水
 */
@Aspect
@Component
public class LogAspect
{
    /**
     * 日志記錄log
     */
    public transient Logger log = Logger.getLogger(getClass());

    @Around(value = "@annotation(l)", argNames = "l")
    public Object aroundBase(ProceedingJoinPoint point, Log l)
    {
        RecordMessage recordMessage = new RecordMessage();
        Long startTime = System.currentTimeMillis();
        Object object = null;

        try
        {
            /* 記錄下當前時間 作為請求起始時間 */
            recordMessage.setRequestTime(TimeUtil.getLongDateString(Calendar.getInstance().getTime()));

            /* 獲取請求的信息 */
            getRequestParams(point, recordMessage);

            /* 執行請求的方法 */
            object = point.proceed();

            /* 記錄下當前時間 作為響應時間 */
            recordMessage.setResponseTime(TimeUtil.getLongDateString(Calendar.getInstance().getTime()));

            /* 記錄響應參數 */
            recordMessage.setResponseParames(object == null ? "" : JSON.toJSONString(object));
        }
        catch (Throwable e)
        {
            log.warn("proceed GW Interface throwable, ", e);
        }
        finally
        {
            Long endTime = System.currentTimeMillis();
            recordMessage.setCostTime(endTime - startTime);
            /* 記錄接口日志 */
            log.info(recordMessage.toString());
        }
        return object;
    }

    /**
     * 從切點中解析出該切點對應的方法
     * @param point point
     * @throws ClassNotFoundException
     * @throws IOException
     * @author 洪墨水
     */
    private void getRequestParams(ProceedingJoinPoint point, RecordMessage recordMessage) throws ClassNotFoundException, IOException
    {
        /* 類名 */
        String targetObject = point.getTarget().getClass().getName();
        /* 方法名 */
        String methodName = point.getSignature().getName();

        recordMessage.setTargetObject(targetObject);
        recordMessage.setMethod(methodName);

        Object[] args = point.getArgs();

        Class<?> targetClass = Class.forName(targetObject);

        Method[] methods = targetClass.getMethods();

        StringBuilder requestBuilder = new StringBuilder(0);

        /**
         * 遍歷方法 獲取能與方法名相同且請求參數個數也相同的方法
         */
        for (Method method : methods)
        {
            if (!method.getName().equals(methodName))
            {
                continue;
            }

            Class<?>[] classes = method.getParameterTypes();

            if (classes.length != args.length)
            {
                continue;
            }

            for (int index = 0; index < classes.length; index++)
            {
                requestBuilder.append(args[index] == null ? "" : JSON.toJSONString(args[index]));
            }

            recordMessage.setRequestParames(requestBuilder.toString());
        }

        return;
    }

    @Pointcut(value = "execution(* hongmoshui.com.cnblogs.www.work.service.impl.*.*(..))")
    public void getValuePointCut()
    {
    }

    @After(value = "getValuePointCut()")
    public void after()
    {
        System.out.println("方法執行結束...");
    }

}

/**
 * 日志記錄對象
 * @author 洪墨水
 */
class RecordMessage
{
    /**
     * 請求的方法
     */
    private String method;

    /**
     * 請求方法所在的對象
     */
    private String targetObject;

    /**
     * 請求參數
     */
    private String requestParames;

    /**
     * 請求時間
     */
    private String requestTime;

    /**
     * 響應時間
     */
    private String responseTime;

    /**
     * 響應參數
     */
    private String responseParames;

    /**
     * 請求的來源IP
     */
    private String requestIp;

    /**
     * 方法執行的耗時,毫秒
     */
    private long costTime;

    /**
     * 請求的方法
     */
    public String getMethod()
    {
        return method;
    }

    /**
     * 請求的方法
     */
    public void setMethod(String method)
    {
        this.method = method;
    }

    /**
     * 請求方法所在的對象
     */
    public String getTargetObject()
    {
        return targetObject;
    }

    /**
     * 請求方法所在的對象
     */
    public void setTargetObject(String targetObject)
    {
        this.targetObject = targetObject;
    }

    /**
     * 請求參數
     */
    public String getRequestParames()
    {
        return requestParames;
    }

    /**
     * 請求參數
     */
    public void setRequestParames(String requestParames)
    {
        this.requestParames = requestParames;
    }

    /**
     * 請求時間
     */
    public String getRequestTime()
    {
        return requestTime;
    }

    /**
     * 請求時間
     */
    public void setRequestTime(String requestTime)
    {
        this.requestTime = requestTime;
    }

    /**
     * 響應時間
     */
    public String getResponseTime()
    {
        return responseTime;
    }

    /**
     * 響應時間
     */
    public void setResponseTime(String responseTime)
    {
        this.responseTime = responseTime;
    }

    /**
     * 響應參數
     */
    public String getResponseParames()
    {
        return responseParames;
    }

    /**
     * 響應參數
     */
    public void setResponseParames(String responseParames)
    {
        this.responseParames = responseParames;
    }

    /**
     * 請求的來源IP
     */
    public String getRequestIp()
    {
        return requestIp;
    }

    /**
     * 請求的來源IP
     */
    public void setRequestIp(String requestIp)
    {
        this.requestIp = requestIp;
    }

    /**
     * 方法執行的耗時,毫秒
     */
    public long getCostTime()
    {
        return costTime;
    }

    /**
     * 方法執行的耗時,毫秒
     */
    public void setCostTime(long costTime)
    {
        this.costTime = costTime;
    }

    /**
     * toString
     * @return String String
     * @author 洪墨水
     */
    @Override
    public String toString()
    {
        StringBuilder sBuilder = new StringBuilder(0);

        sBuilder.append("method=").append(method);
        sBuilder.append(", targetObject=").append(targetObject);
        sBuilder.append(", requestParames=").append(requestParames);
        sBuilder.append(", requestTime=").append(requestTime);
        sBuilder.append(", responseTime=").append(responseTime);
        sBuilder.append(", responseParames=").append(responseParames);
        sBuilder.append(", requestIp=").append(requestIp);
        sBuilder.append(", costTime=").append(costTime);

        return sBuilder.toString();
    }

}

時間工具類:

package hongmoshui.com.cnblogs.www.base.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import org.apache.commons.lang3.StringUtils;

/**
 * 時間工具類
 * @author 洪墨水
 */
public class TimeUtil
{
    private static int i = 0;

    /**
     * 日期轉換成 yyyy-MM-dd HH:mm:ss+時區形式 如:2019-04-24 19:18:03+0800
     * @param date 日期
     * @return 按格式返回日期
     * @author 洪墨水
     */
    public static String getDateString(Date date)
    {
        if (date == null)
        {
            return null;
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");

        return dateFormat.format(date);
    }

    /**
     * 日期轉換成 yyyy-MM-dd HH:mm:ss 形式 如:2019-04-24 19:18:03
     * @param date 日期
     * @return 按格式返回日期
     * @author 洪墨水
     */
    public static String dateToString()
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.SECOND, now.get(Calendar.SECOND) + i);

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        i++;
        if (i > 1)
        {
            i = 0;
        }
        return dateFormat.format(now.getTime());
    }

    /**
     * 日期轉換成 yyyy-MM-dd HH:mm:ss+時區形式 如:2019-04-24 19:18:03+0800
     * @param date 日期
     * @return 按格式返回日期
     * @author 洪墨水
     */
    public static String getDateString(String date)
    {
        if (date == null)
        {
            return null;
        }
        return TimeUtil.getDateString(toDate(date, "yyyy-MM-dd HH:mm:ss"));
    }

    /**
     * 
     * String轉 Date
     * @param date 日期
     * @param format 格式
     * @return 轉換后日期
     * @author 洪墨水
     */
    public static Date toDate(String date, String format)
    {
        if (StringUtils.isEmpty(format))
        {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        SimpleDateFormat df = new SimpleDateFormat(format);
        try
        {
            return df.parse(date);
        }
        catch (ParseException e)
        {
            return new Date();
        }
    }

    /**
     * 
     * String轉 Date
     * @param date 日期
     * @param format 格式
     * @return 轉換后日期
     * @author 洪墨水
     */
    public static Date toDate(String date)
    {
        return toDate(date, null);
    }

    /**
     * 將帶時區的時間字符串轉換成系統所在時區的時間 如:2019-04-24 19:18:03+0700 轉換到東八區的時間為:2019-04-24
     * 20:18:03
     * @param dateformat 日期格式
     * @return 系統所在時區的時間
     * @throws ParseException [參數說明]
     * @author 洪墨水
     */
    public static Date convertToLocalDate(String dateformat) throws ParseException
    {
        SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");

        Date date = dFormat.parse(dateformat);

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.setTimeZone(TimeZone.getDefault());

        return calendar.getTime();
    }

    /**
     * <獲取當前時間N小時后的時間 >
     * @param n 小時
     * @return 日期
     * @author 洪墨水
     */
    public static Date getNextDate(int n)
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.HOUR_OF_DAY, now.get(Calendar.HOUR_OF_DAY) + n);
        return now.getTime();
    }

    /**
     * <獲取當前時間N天后的凌晨 >
     * @param n 天
     * @return 日期
     * @author 洪墨水
     */
    public static Date getMorningNextDate(int n)
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.DATE, now.get(Calendar.DATE) + n);// 設置時間向前進n天
        now.set(Calendar.HOUR_OF_DAY, 0);
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        return now.getTime();
    }

    /**
     * <獲取當前時間N小時后的整點時間 >
     * @param n 小時
     * @return 日期
     * @author 洪墨水
     */
    public static Date getNextHour(int n)
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.DATE, now.get(Calendar.DATE));
        now.set(Calendar.HOUR_OF_DAY, now.get(Calendar.HOUR_OF_DAY) + n);// 設置時間向前進n小時
        return now.getTime();
    }

    /**
     * <獲取當前時間N天后的凌晨【精確到毫秒】 >
     * @param n 前進天數
     * @return Date [日期]
     * @author 洪墨水
     */
    public static Date getMorningNextDateMillisecond(int n)
    {
        Calendar now = Calendar.getInstance();
        now.set(Calendar.DATE, now.get(Calendar.DATE) + n);// 設置時間向前進n天
        now.set(Calendar.HOUR_OF_DAY, 0);
        now.set(Calendar.MINUTE, 0);
        now.set(Calendar.SECOND, 0);
        now.set(Calendar.MILLISECOND, 0);
        return now.getTime();
    }

    /**
     * 比較
     * @param date 日期
     * @return 是否是今天
     * @author 洪墨水
     */
    public static boolean checkLastDate(Date date)
    {
        Date d = new Date();
        Calendar current = Calendar.getInstance();
        current.setTime(date);
        Calendar start = Calendar.getInstance();
        Calendar end = Calendar.getInstance();
        start.set(Calendar.YEAR, current.get(Calendar.YEAR));
        start.set(Calendar.MONTH, current.get(Calendar.MONTH));
        start.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
        start.set(Calendar.HOUR_OF_DAY, 0);
        start.set(Calendar.MINUTE, 0);
        start.set(Calendar.SECOND, 0);
        end.set(Calendar.YEAR, current.get(Calendar.YEAR));
        end.set(Calendar.MONTH, current.get(Calendar.MONTH));
        end.set(Calendar.DAY_OF_MONTH, current.get(Calendar.DAY_OF_MONTH));
        end.set(Calendar.HOUR_OF_DAY, 23);
        end.set(Calendar.MINUTE, 59);
        end.set(Calendar.SECOND, 59);
        if (d.after(start.getTime()) && d.before(end.getTime()))
        {
            return true;
        }
        return false;
    }

    /**
     * 獲取日期;格式:yyyy-MM-dd
     * @param date 日期
     * @return String yyyy-MM-dd格式的日期字符串
     * @author 洪墨水
     */
    public static String getDate(Date date)
    {
        SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM-dd");
        dFormat.setTimeZone(TimeZone.getDefault());
        return dFormat.format(date);
    }

    /**
     * <獲取年月>
     * @param date 時間
     * @return String [獲取年月]
     * @author 洪墨水
     */
    public static String getDateYearAndMonth(Date date)
    {
        SimpleDateFormat dFormat = new SimpleDateFormat("yyyy-MM");
        dFormat.setTimeZone(TimeZone.getDefault());
        return dFormat.format(date);
    }

    /**
     * 獲取有效時間
     * @return 有效時間
     * @author 洪墨水
     */
    public static int getExpireTime()
    {
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.SECOND, 59);
        return (int) ((cal.getTime().getTime() - new Date().getTime()) / 1000);
    }

    /**
     * <時間增加>
     * @param p 時間日期
     * @param number 要增加數
     * @param filed 域
     * @return Date [增加后的時間]
     * @author 洪墨水
     */
    public static Date addDate(Date p, int number, int filed)
    {
        Calendar cal = Calendar.getInstance();
        cal.setTime(p);
        cal.add(filed, number);
        return cal.getTime();
    }

    /**
     * <時間戳轉日期時間>
     * @param s 時間戳
     * @return String [日期時間]
     * @author 洪墨水
     */
    public static String stampToDate(String s, String format)
    {
        if (StringUtils.isEmpty(format))
        {
            format = "yyyy-MM-dd HH:mm:ss";
        }
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }
    
    /**
     * 日期轉換成 yyyy-MM-dd HH:mm:ss zzz+時區形式 如:2019-04-24 19:18:03 132+0800
     * @param date 日期
     * @return LongDate
     * @author 洪墨水
     */
    public static String getLongDateString(Date date)
    {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SZ");

        return dateFormat.format(date);
    }
}

aop切面類中的@Pointcut的用法:

格式:

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?) 

括號中各個pattern分別表示:

  • 修飾符匹配(modifier-pattern?)
  • 返回值匹配(ret-type-pattern)可以為*表示任何返回值,全路徑的類名等
  • 類路徑匹配(declaring-type-pattern?)
  • 方法名匹配(name-pattern)可以指定方法名 或者 *代表所有, set* 代表以set開頭的所有方法
  • 參數匹配((param-pattern))可以指定具體的參數類型,多個參數間用“,”隔開,各個參數也可以用“*”來表示匹配任意類型的參數,如(String)表示匹配一個String參數的方法;(*,String) 表示匹配有兩個參數的方法,第一個參數可以是任意類型,而第二個參數是String類型;可以用(..)表示零個或多個任意參數
  • 異常類型匹配(throws-pattern?)
  • 其中后面跟着“?”的是可選項

注:詳細信息請看----切面AOP的切點@Pointcut用法

 四、測試類

package hongmoshui.com.cnblogs.www.work.service.impl;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import hongmoshui.com.cnblogs.www.base.dao.RedisClientDao;
import hongmoshui.com.cnblogs.www.base.model.Result;
import hongmoshui.com.cnblogs.www.work.annotation.Log;
import hongmoshui.com.cnblogs.www.work.dao.TestDao;
import hongmoshui.com.cnblogs.www.work.dao.TestQueryDao;
import hongmoshui.com.cnblogs.www.work.model.UserInfo;
import hongmoshui.com.cnblogs.www.work.service.TestService;

@Service("testService")
public class TestServiceImpl implements TestService
{
    @Autowired
    private transient RedisClientDao redisClientDao;/**
     * 日志記錄log
     */
    public transient Logger log = Logger.getLogger(getClass());

    @Log(name = "getValue")
    @Override
    public Result getValue(String key)
    {
        Result result = new Result();
        Object obj = redisClientDao.get(key);
        if (obj != null)
        {
            result.setSuccess(true);
            result.setMessage("取出成功!");
            result.put("value", obj);
            log.info("call redis get success! redis key:" + key + ",value:" + obj);
        }
        else
        {
            result.setSuccess(false);
            result.setMessage("取出失敗!");
            log.error("call redis get failed! redis key:" + key + ",value:" + obj);
        }
        return result;
    }
}

測試結果:

2019-04-22 15:36:51 [hongmoshui.com.cnblogs.www.base.aop.LogAspect]-[INFO] method=getValue, targetObject=hongmoshui.com.cnblogs.www.work.service.impl.TestServiceImpl, requestParames="hongmoshui_01", requestTime=2019-04-22 15:36:51 134+0800, responseTime=2019-04-22 15:36:51 250+0800, responseParames={"message":"取出成功!","value":"我是01","success":true}, requestIp=null, costTime=119
方法執行結束...

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM