Spring通过包名进行日志记录

发布于 2024-09-15 13:50:40 字数 116 浏览 12 评论 0原文

我需要在项目中的某些包中记录许多类,但我无法更改其源代码。 所以我需要一个可以指定包名称的解决方案,并使用 spring aop 将日志记录添加到该包的类而不更改它们,但我不知道如何做到这一点。 我怎样才能做到这一点?

I need to log many classes in some packages in a project which I can not change its source code.
So I need a solution which I can specify package name, and with spring aop add logging to that package's classes without change them but I dont know how can I do that.
How can I do that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

柒七 2024-09-22 13:50:40

使用 Spring AOP,您只能记录这些用作 Spring Bean 的类,即使这样,您也只能记录公共方法的执行。

这是 @AspectJ 通知中的一个方面(这是与“真正的 AspectJ”和 Spring AOP 兼容的样式,请阅读有关差异的信息 在 spring 参考中),您可以在 Spring AOP 和 AspectJ 字节中使用代码编织:

@Aspect
public class LoggingAspect{

    @Pointcut("execution(* com.mycompany.myproject.*.*(..))")
    public void methodToLog(){
    };

    @Around("methodToLog()")
    public Object logMethod(final ProceedingJoinPoint joinPoint) throws Throwable{
        final StaticPart staticPart = joinPoint.getStaticPart();
        final String sig =
            "" + staticPart.getSignature() + " with args: "
                + Arrays.deepToString(joinPoint.getArgs());
        System.out.println("Entering method " + sig);
        final Object result = joinPoint.proceed();
        System.out.println("Leaving method " + sig);
        return result;
    }

}

这是一个带有一些方法的愚蠢类:

package com.mycompany.myproject;
public class Dummy1{

    public static void main(final String[] args){
        final Dummy1 dummy = new Dummy1();
        dummy.doSomeStuff();
        dummy.doSomeStuffWithSomeArgs("Hello", 123);
    }

    private void doSomeStuff(){}

    public void doSomeStuffWithSomeArgs(final String firstArg,
        final int secondArg){}

}

当您在 Eclipse / AJDT 中将此类作为 Java/AspectJ 应用程序启动时,您会得到以下输出:

Entering method void com.mycompany.myproject.Dummy1.main(String[]) with args: [[]]
Entering method void com.mycompany.myproject.Dummy1.doSomeStuff() with args: []
Leaving method void com.mycompany.myproject.Dummy1.doSomeStuff() with args: []
Entering method void com.mycompany.myproject.Dummy1.doSomeStuffWithSomeArgs(String, int) with args: [Hello, 123]
Leaving method void com.mycompany.myproject.Dummy1.doSomeStuffWithSomeArgs(String, int) with args: [Hello, 123]
Leaving method void com.mycompany.myproject.Dummy1.main(String[]) with args: [[]]

要在 Spring AOP 中测试它会涉及更多工作(主要方法方法不会)如果不工作,您将必须创建一个 ApplicationContext 并注册一个 Dummy1 类型的 bean,您将在其上调用方法),所以我将把它留给您,但我很确定私有方法调用不会被记录。

如果您下载 SpringSource 工具套件,您将获得用于方面可视化和测试的好工具。即使您只想使用 Spring AOP,您也应该阅读 AspectJ 书。这是一本很棒的书。


顺便说一句:您显然会想要使用真正的记录器,而不是 system.out。您可以为每个方面定义一个,或者(仅对于真正的方面)您可以将其作为目标类中的静态成员引入以获取每个类的日志记录。我认为 AspectJ 的杀手级功能。

With Spring AOP you can only log these classes if they are used as Spring Beans, and even then you can only log public method executions.

Here is an aspect in @AspectJ notification (this is the style that is compatible with both "real AspectJ" and Spring AOP, read about the difference in the spring reference) that you can use in both Spring AOP and AspectJ byte code weaving:

@Aspect
public class LoggingAspect{

    @Pointcut("execution(* com.mycompany.myproject.*.*(..))")
    public void methodToLog(){
    };

    @Around("methodToLog()")
    public Object logMethod(final ProceedingJoinPoint joinPoint) throws Throwable{
        final StaticPart staticPart = joinPoint.getStaticPart();
        final String sig =
            "" + staticPart.getSignature() + " with args: "
                + Arrays.deepToString(joinPoint.getArgs());
        System.out.println("Entering method " + sig);
        final Object result = joinPoint.proceed();
        System.out.println("Leaving method " + sig);
        return result;
    }

}

Here is a stupid class with some methods:

package com.mycompany.myproject;
public class Dummy1{

    public static void main(final String[] args){
        final Dummy1 dummy = new Dummy1();
        dummy.doSomeStuff();
        dummy.doSomeStuffWithSomeArgs("Hello", 123);
    }

    private void doSomeStuff(){}

    public void doSomeStuffWithSomeArgs(final String firstArg,
        final int secondArg){}

}

When you start this class in Eclipse / AJDT as Java/AspectJ application, you get the following output:

Entering method void com.mycompany.myproject.Dummy1.main(String[]) with args: [[]]
Entering method void com.mycompany.myproject.Dummy1.doSomeStuff() with args: []
Leaving method void com.mycompany.myproject.Dummy1.doSomeStuff() with args: []
Entering method void com.mycompany.myproject.Dummy1.doSomeStuffWithSomeArgs(String, int) with args: [Hello, 123]
Leaving method void com.mycompany.myproject.Dummy1.doSomeStuffWithSomeArgs(String, int) with args: [Hello, 123]
Leaving method void com.mycompany.myproject.Dummy1.main(String[]) with args: [[]]

To test this in Spring AOP would involve more work (the main method approach won't work, you will have to create an ApplicationContext and register a bean of type Dummy1, on which you will call the methods), so I'll leave that to you, but I am pretty sure the private method call will not be logged.

If you download the SpringSource Tool Suite, you get nice tools for aspect visualisation and testing. You should also read the AspectJ book, even if you only want to use Spring AOP. It's a great book.


BTW: you will obviously want to use a real logger, not system.out. You can either define one per aspect, or (only with real aspectj) you can introduce it as a static member in the target class to get per-class logging. A killer feature of AspectJ in my opinion.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文