如何在方面

时间:2017-12-12 11:29:50

标签: java spring logging aspectj spring-aop

我正在尝试创建一个通用的Logger,这将是一个小的独立代码。不同的应用程序可以使用此Logger进行日志记录 比方说,有两个不同的代码库 - CB1和CB2 CB1需要捕获包CB1 / a / b / c下所有类的所有公共方法 CB2需要捕获包CB2 / d / e / f

下所有类的所有公共方法

现在,我到现在所做的一切如下 -
一个新的代码库,比如LogUtility,它有一个Aspect GenericLogger -

public class GenericLogger {
   public Object aroundLog(ProceedingJoinPoint jp) {
      //logging code goes here
   }
}
some_context.xml中的

-

<aop:config>

    <aop:aspect id="loggerAspect" ref="myLogger">

        <aop:pointcut id="sample" expression="${logger.pointcutExpr}" />

        <aop:around method="aroundLog" pointcut-ref="sample" />

    </aop:aspect>

</aop:config>

如果CB1需要使用此LogUtility,CB1会将LogUtility添加到其pom / ivy依赖项中,并在应用程序启动时通过属性文件提供${logger.pointcutExpr}的值。

因此,对于CB1,CB2,......它的工作方式很好。

我认为这种方法的唯一缺点是属性文件中包含单个密钥的长列表,即logger.pointcutExpr 好的是,每当需要更改代码库时,只需在自己的属性文件中添加新的切入点即可。因此,单个Aspect可以为多个代码库提供服务。

早些时候,我试图做这样的事情,

@Aspect
@Component
public class GenericLogger {

   @Around(<can't make this dynamic>)
   public object aroundLog(ProceedingJoinPoint jp) {
      //logging code goes here
   }
}

上面的问题是传递给任何注释的值必须是最终的,所以不能采用这种方法。

我想知道在飞行中是否有任何可以做到的事情 1.在不明确创建属性文件的情况下,不同代码库可以提供键logger.pointcutExpr的值的任何方式 2.或者是否可以动态注册切入点?

我一直在谷歌上搜索,我到处都找到了基本的AOP教程。我认为要做这样的事情我需要在SpringJOP中深入挖掘AspectJ。我在下面找到了链接 -
https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-choosing how to apply spring aop for legacy code by taking pointcut as input from user https://eclipse.org/aspectj/doc/next/devguide/ltw-configuration.html

我对AspectJ有基本知识,我正在寻找的可能是愚蠢的。

1 个答案:

答案 0 :(得分:0)

您可以使用static final表达式使Around方法中的内容动态化(排序)。

但我会提出别的建议。

你绝对可以在AspectJ中做这类事情,只是你需要首先将Aspect视为描述将为所有情况的超级集执行的表达式。然后在方面内定义您想要实现的行为。因此,例如,您可以使用Object target = joinPoint.getTarget();来获取目标(执行该方法的类),然后使用String canonicalName = taget.getCanonicalName(),其中包含名称中的包,然后您可以执行以下操作: / p>

if(getCanonicalName.contains("some/package") {
    System.out.println("You can do better than this if statement");
}

并制作if语句,以区分规范名称中包含的各种包。这样你就可以更好地控制每个包的内容。