如何使用spring AOP而不是代理来记录实际的存储库类名?

时间:2017-02-03 14:47:03

标签: java spring-data spring-aop

我正在尝试使用AOP记录存储库类名。但是在运行时我在日志中获取代理类名称,因为我在我的项目中使用了spring数据,因此有一个用于存储库的接口,它将在春天实现。请提出答案,因为我花了很多时间找到相同的答案。

以下是执行后生成的日志。

    className - No of records returned : 38
  2017-02-03 19:54:43,360 [INFO]   className - Exiting  method:  getAlertPatterns]
  2017-02-03 19:54:43,360 [INFO]   className - No of records returned : 38
  2017-02-03 19:54:43,360 [INFO]   className - Exiting  method:  getAlertPatterns]
  2017-02-03 19:54:43,363 [INFO]   controllerClassName - Exiting method:  getAlertPatterns]
  2017-02-03 19:54:46,457 [INFO]   controllerClassName - ActionTakenController***Entering  method:  getAlertActions]
  2017-02-03 19:54:46,458 [INFO]   className - ActionTakenServiceImpl****Entering  method:  getAlertActions]
  2017-02-03 19:54:46,458 [INFO]   className - $Proxy158****Entering  method:  getAlertActions]
  2017-02-03 19:54:46,510 [INFO]   repositoryClassName - java.util.ArrayList***
  2017-02-03 19:54:46,511 [INFO]   repositoryClassName - No of records returned : 2
  2017-02-03 19:54:46,511 [INFO]   repositoryClassName - Exiting method:  getAlertActions]
  2017-02-03 19:54:46,511 [INFO]   className - No of records returned : 2
  2017-02-03 19:54:46,511 [INFO]   className - Exiting  method:  getAlertActions]
  2017-02-03 19:54:46,511 [INFO]   className - No of records returned : 2
  2017-02-03 19:54:46,512 [INFO]   className - Exiting  method:  getAlertActions]
  2017-02-03 19:54:46,512 [INFO]   controllerClassName - Exiting method:  getAlertActions]
  2017-02-03 19:54:50,488 [INFO]   controllerClassName - InitialAnalysisController***Entering  method:  getAlertInitialAnalysis]
  2017-02-03 19:54:50,495 [INFO]   className - InitialAnalysisServiceImpl****Entering  method:  getAlertInitialAnalysis]
  2017-02-03 19:54:50,505 [INFO]   className - $Proxy144****Entering  method:  getAlertInitialAnalysis]

用于配置aop类的代码如下

    private Logger logger = LogManager.getLogger("");

    /** Pointcut for execution of methods on {@link Service} annotation */
    @Pointcut("execution(public * (@org.springframework.web.bind.annotation.RestController com.nscorp.apps.wds.controller..*).*(..))")
    public void controllerCalls() {
        /** Pointcut for execution of methods on {@link Service} annotation */
    }

    /** Pointcut for execution of methods on {@link Service} annotation */
    @Pointcut("execution(public * (@org.springframework.stereotype.Service com.nscorp.apps.wds.services..*).*(..))")
    public void serviceAnnotation() {
        /** Pointcut for execution of methods on {@link Service} annotation */
    }

    /** Pointcut for execution of methods on {@link Repository} annotation */
    @Pointcut("execution(public * (@org.springframework.stereotype.Repository com.nscorp.apps.wds.dao..*).*(..))")
    public void repositoryAnnotation() {
        /** Pointcut for execution of methods on {@link Repository} annotation */
    }

    /** Pointcut for execution of methods on {@link JpaRepository} interfaces */
    @Pointcut("this (org.springframework.data.repository.Repository)")
    public void jpaRepository() {
        /** Pointcut for execution of methods on {@link JpaRepository} interfaces */
    }
    /** Pointcut for execution of combined  methods serviceAnnotation() and controllerCalls() */
    @Pointcut("serviceAnnotation()   || jpaRepository()  ")
    public void performanceMonitor() {
        /** Pointcut for execution of combined  methods serviceAnnotation() and controllerCalls() */
    }

    /** Pointcut for execution of combined  methods repositoryAnnotation() and jpaRepository()*/
    @Pointcut(" jpaRepository()  ")
    public void jpaTransactionlogs() {
        /** Pointcut for execution of combined  methods repositoryAnnotation() and jpaRepository()*/
    }

    @Pointcut(" controllerCalls() ")
    public void controllerParamCalls() {
        //buisenessCalls
    }


    @Around("controllerParamCalls()")
    public Object controllerClassName(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info(joinPoint.getTarget().getClass().getSimpleName()+"***" +"Entering  method:  " + joinPoint.getSignature().getName() + "]");

           Object[] signatureArgs = joinPoint.getArgs();
           for (Object signatureArg: signatureArgs) {
               logger.info( "The arguments are ----" + signatureArg);
           }


        Object obj = joinPoint.proceed();
        if (obj instanceof Collection) {
            logger.info("No of records returned : " + ((Collection<?>) obj).size());

        }
        logger.info("Exiting method:  " + joinPoint.getSignature().getName() + "]");
        return obj;
    }

    @Around("performanceMonitor()")
    public Object className(ProceedingJoinPoint joinPoint) throws Throwable {
        logger.info(joinPoint.getTarget().getClass().getSimpleName() +"****" +"Entering  method:  " + joinPoint.getSignature().getName() + "]");
        Object obj = joinPoint.proceed();
        if (obj instanceof Collection) {
            logger.info("No of records returned : " + ((Collection) obj).size());

        }
        logger.info("Exiting  method:  " + joinPoint.getSignature().getName() + "]");
        return obj;
    }

示例存储库类是

    @Repository
public interface ActionTakenRepository extends CrudRepository<ActionTaken, BigInteger> {

    @Query("Select actionTaken from ActionTaken actionTaken where actionTaken.status NOT IN (Select codeId from Codes where codeType='"+CommonConstants.INACTIVE+"') order by auditCreatedAt desc")
    List<ActionTaken> getAlertActions(); 
}

3 个答案:

答案 0 :(得分:0)

代替joinPoint.getTarget().getClass().getSimpleName()尝试使用

joinPoint.getSignature().getDeclaringTypeName()

获取实际的类名(包括软件包)。

此外,要获取执行的方法名称:

joinPoint.getSignature().getName()

joinPoint的类型为 org.aspectj.lang.ProceedingJoinPoint

答案 1 :(得分:0)

如果我正确理解了这些问题,您将想要提取该数组中的接口

joinPoint.getThis().getClass().getGenericInterfaces();

你可以梳理一下接口的名称。

答案 2 :(得分:0)

您也可以使用 Advised.getProxiedInterfaces() 并获取实际的接口名称。

我对类似问题的answer提供了更多详细信息。