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

zzlelutf  于 2023-03-16  发布在  Spring
关注(0)|答案(2)|浏览(227)

我已经实现了面向方面的日志记录的目的。
记录方面

@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("******");
  }
}

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

<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>

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

logBefore() is running!
classname : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint,getConnection
******

请指教

pkln4tw6

pkln4tw61#

我永远不明白为什么那么多开发人员调用JoinPoint上的方法来提取他们在记录joinpoint示例本身时免费获得的特定信息。连接点类型,具有类名和返回类型的方法签名。如果你真的想知道你的方面中发生了什么,这就是你所需要的。通过仅仅记录一部分信息来隐藏信息会使调试变得困难得多。另外,调用大量的方法并不能使记录方面更快。然后他们抱怨AOP“慢”。- )
无论如何,不管怎样,您希望在这里使用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()为您提供了真实的的类,而不是代理类。

nzk0hqpo

nzk0hqpo2#

我参加派对可能会迟到,但这对某人可能有帮助。
我相信@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>..*.*(..)),以仅启用公共方法的日志记录。

相关问题