访问来自AspectJ的私有静态构件(例如记录器)

问题描述 投票:0回答:1

假设我有这个类

public class MyClass {
    private Logger log = LogFactory.getLogger(MyClass.class);

    public void doSomething() {
        // doing something
    }
}

假设我想写一个方面登录进入和退出:

public aspect TraceAspect {

    pointcut method(): execution(* *(..));

    before(): method(){

        log.info("entering method");
    }

    after(): method(){
        log.info("existing method");
    }
}

这里的问题是,我想访问与方面的类中的日志对象,但我不知道怎么办。我不希望创建一个新的记录,因为我想保持登录时与类logger相关的所有数据。有没有一种方法或访问类数据的模式?

编辑:要说明这方面应跟踪有日志领域的所有课程。也就是说,我可能有许多类:MyClass, MyClass1, YourClass2, RepositoryClass,等。

java aspectj
1个回答
1
投票

什么Nándor说,在技术上是正确的,但我的建议是:请避免访问私有成员或方法时,你可以,因为他们是私人的一个原因。例如,他们有可能发生变化,即使一个类的公共接口并没有改变。所以,你可以永远依靠它们的存在或它们命名。此外,横切关注点也应符合设计原理类似封装尽可能。

这种特定的情况下是约SLF4J记录器,更准确地了解你的愿望,以避免产生多余的日志对象。那么,SLF4J是不是傻还是不小心,你可能会认为有关创建对象。所有执行ILoggerFactory类,以现有的缓存记录仪对于给定的(类)名称中使用的内部地图,例如见

那么,为什么你不只是放松和使用目标类的名字从你的方面访问相应的记录器。这甚至工作,如果目标类不具有其自己的静态记录:

应用类:

package de.scrum_master.app;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClassWithLogger {
  private Logger log = LoggerFactory.getLogger(MyClassWithLogger.class);

  public void doSomething() {}
}
package de.scrum_master.app;

public class MyClassWithoutLogger {
  public void doSomething() {}
}
package de.scrum_master.app;

public class Application {
  public static void main(String[] args) {
    new MyClassWithLogger().doSomething();
    new MyClassWithoutLogger().doSomething();
  }
}

方面:

package de.scrum_master.aspect;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public aspect TraceAspect {
  pointcut executedMethods(Object targetObject) :
    execution(!static * *(..)) && target(targetObject);

  before(Object targetObject) : executedMethods(targetObject) {
    Logger log = LoggerFactory.getLogger(targetObject.getClass());
    log.info("Entering " + thisJoinPoint);
  }

  after(Object targetObject) : executedMethods(targetObject) {
    Logger log = LoggerFactory.getLogger(targetObject.getClass());
    log.info("Exiting " + thisJoinPoint);
  }
}

控制台日志,SLF4J配置为使用简单的记录:

[main] INFO de.scrum_master.app.MyClassWithLogger - Entering execution(void de.scrum_master.app.MyClassWithLogger.doSomething())
[main] INFO de.scrum_master.app.MyClassWithLogger - Exiting execution(void de.scrum_master.app.MyClassWithLogger.doSomething())
[main] INFO de.scrum_master.app.MyClassWithoutLogger - Entering execution(void de.scrum_master.app.MyClassWithoutLogger.doSomething())
[main] INFO de.scrum_master.app.MyClassWithoutLogger - Exiting execution(void de.scrum_master.app.MyClassWithoutLogger.doSomething())
© www.soinside.com 2019 - 2024. All rights reserved.