无法使用@Before Aspect获取类名和方法

时间:2018-06-02 12:33:59

标签: aspectj spring-aop

我已经实现了AOP用于记录目的。

LoggingAspect

findByEmployeeIdIn(List<Long> ids)

以及app-ctx.xml中的以下配置

@Aspect
public class LoggingAspect {
  private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LoggingAspect.class);

  @Before("execution(public * *(..))")
  public void logBefore(JoinPoint joinPoint) {
    System.out.println("logBefore() is running!");
    System.out.println("classname : " + joinPoint.getClass().getCanonicalName() + "," + joinPoint.getSignature().getName());
    System.out.println("******");
  }
}

但它为我得到的所有类输出

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
   http://www.springframework.org/schema/beans     
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
   http://www.springframework.org/schema/context 
   http://www.springframework.org/schema/context/spring-context-3.0.xsd
   http://www.springframework.org/schema/aop 
   http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
   http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:component-scan
        base-package="com.pms" />
    <aop:aspectj-autoproxy />
<bean id="loggingAspect"
        class="com.pms.advice.LoggingAspect" />
</beans>

请咨询

2 个答案:

答案 0 :(得分:0)

我永远不会理解为什么这么多开发人员在JoinPoint上调用方法,以便在仅记录joinpoint实例本身时提取他们免费获得的特定信息。有一切:连接点类型,带有类名和返回类型的方法签名。如果您真的想知道您方面的情况,那么这就是您所需要的。通过仅记录其中的一部分来隐藏信息会使调试变得更加困难。此外,调用许多方法并不会使日志记录方面更快。然后他们抱怨说AOP慢了#34; ; - )

无论如何,为了它的价值,你想在这里使用joinPoint.getSignature().getDeclaringTypeName()。您要记录的是连接点类和截获方法的名称。

注意,joinPoint.getSignature().getDeclaringType()会为您提供动态代理的类型,这可能不是您想要的。

更新:如果您使用((MethodSignature) thisJoinPoint.getSignature()).get*(),则可以访问更多的getter:

Method getMethod()
Class getReturnType()
Class[] getParameterTypes()
Class[] getExceptionTypes()
String[] getParameterNames()
String toString()
int getModifiers()
String getName()
String toShortString()
String toLongString()
Class getDeclaringType()
String getDeclaringTypeName()

而且,有趣的是,在这种情况下((MethodSignature) thisJoinPoint.getSignature()).getDeclaringType()为您提供真正的类,而不是代理类。

答案 1 :(得分:0)

我可能聚会晚了,但可能会帮助某人。

我相信@Aaruhi希望记录其实现的类。如果答案是肯定的,那么这将有所帮助:

@Before("execution(* <your_pakage_name>..*.*(..))")
public void logBefore(JoinPoint joinPoint) {
   System.out.println("logBefore() is running!");
   System.out.println("classname : " + joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
   System.out.println("******");
}

这将打印所有私有,公共和内部方法的日志。请更新<your_pakage_name>,这将允许记录属于给定<your_pakage_name>的所有类。

joinPoint.getSignature().getDeclaringTypeName() -这将打印您的实现类名称。

注意-将切入点表达式更新为execution(public * <your_pakage_name>..*.*(..)),以仅启用公共方法的记录。