1. 程式人生 > >SpirngMVC AOP 用註解方式配置切面及IllegalArgumentException: error at ::0 formal unbound in pointcut 異常分析

SpirngMVC AOP 用註解方式配置切面及IllegalArgumentException: error at ::0 formal unbound in pointcut 異常分析

ppi point exc sig 配方 mea oca 代碼 ger

MEAVN代碼

<!-- springAOP核心包 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.0.2.RELEASE</version>
</dependency>
 <!--使用AspectJ方式註解需要相應的包--> 
<dependency>  
    <
groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.9</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version
>1.8.9</version> </dependency>

註意:此處版本號一定要與JDK兼容 否則會報error at ::0 can‘t find referenced pointcut pointCutName 錯誤

spring-mvc.xml 配置

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.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 ">

<!-- 啟用AsjectJ支持 -->
<aop:aspectj-autoproxy proxy-target-class="true" />

註意:下劃線是必須配置的項

註解類配置

import org.apache.log4j.Logger;
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.springframework.stereotype.Component;

/**
 * 采用註解形式進行AOP定義*/
@Aspect    //該標簽把LoggerAspect類聲明為一個切面
@Component //該標簽把LoggerAspect類放到IOC容器中
public class LogAopAction {

    /**
     * execution:用來匹配執行方法的連接點
     * A:@Pointcut("execution(* com.aijava.springcode.service..*.*(..))")
     * 第一個*表示匹配任意的方法返回值,..(兩個點)表示零個或多個,上面的第一個..表示service包及其子包,第二個*表示所有類,第三個*表示所有方法,第二個..表示方法的任意參數個數
     * B:@Pointcut("within(com.aijava.springcode.service.*)")
     * within限定匹配方法的連接點,上面的就是表示匹配service包下的任意連接點
     * C:@Pointcut("this(com.aijava.springcode.service.UserService)")
     * this用來限定AOP代理必須是指定類型的實例,如上,指定了一個特定的實例,就是UserService
     * D:@Pointcut("bean(userService)")
     * bean也是非常常用的,bean可以指定IOC容器中的bean的名稱
     * @within(org.springframework.stereotype.Service),攔截帶有 @Service 註解的類的所有方法
   * @annotation(org.springframework.web.bind.annotation.RequestMapping),攔截帶有@RquestMapping的註解方法
     */
    @Pointcut("execution(* com.cn.xxx..*.*(..))")//把指定包路徑下所有方法都進行匹配
    private void pointCut() {
    }

    /**
     * 方法開始執行
     */
    @Before("pointCut()")
    public void doBefore(JoinPoint point) {

        Class clazz = point.getTarget().getClass();
        String targetName = clazz.getSimpleName();
        String methodName = point.getSignature().getName();
        
        Logger logger = Logger.getLogger(clazz);
        Object[] args = point.getArgs();
        StringBuilder formatLog = new StringBuilder(
                "進入方法 " + clazz.getPackage().getName() + targetName + "." + methodName + ",參數是:");
        for (Object ignored : args) {
            formatLog.append("{},");
        }
        logger.info(formatLog.toString()+args);
    }/**
     * 方法結束執行後的操作
     */
    @AfterReturning(pointcut = "pointCut()", returning = "returnVal")
    public void doAfter(JoinPoint point, Object returnVal) {
        Class clazz = point.getTarget().getClass();
        String targetName = clazz.getSimpleName();
        String methodName = point.getSignature().getName();
        String logString = "退出方法: " + targetName + "." + methodName + ",返回結果是: " + returnVal;
        Logger logger = Logger.getLogger(clazz);
        logger.info(logString);

    }

    /**
     * 方法有異常時的操作
     */
    @AfterThrowing(pointcut = "pointCut()", throwing = "error")
    public void doAfterThrow(JoinPoint point, Throwable error) {

        Class clazz = point.getTarget().getClass();
        String targetName = clazz.getSimpleName();
        String methodName = point.getSignature().getName();
        Logger logger = Logger.getLogger(clazz);
        String logString = " 異常發生在方法: " + targetName + "." + methodName + ",異常為 : ";
        logger.error(logString, error);
    }

    /**
     * AOP環繞方法執行
     * @param pjp
     * @return
     * @throws Throwable
     */
    @Around("pointCut()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        try 
        {
            proceedingJoinPoint.proceed();
        }catch (Exception e) {
            e.toString();
        }
        

    }

}

註意:紅色部分的一定要對應如果不對應就會報 IllegalArgumentException: error at ::0 formal unbound in pointcut 錯誤 ,這個錯誤我排查了好久發現,項目一直啟動錯誤,切記參數一定要對應.

SpirngMVC AOP 用註解方式配置切面及IllegalArgumentException: error at ::0 formal unbound in pointcut 異常分析