То, что Нандор сказал, технически правильно, но мой совет: пожалуйста, избегайте доступа к закрытым членам или методам, когда это возможно, потому что они являются личными по какой-то причине.Например, они могут изменяться, даже если открытый интерфейс класса не изменяется.Таким образом, вы никогда не можете полагаться на их существование или их названия.Кроме того, сквозная задача должна также максимально соответствовать принципам проектирования, таким как инкапсуляция.
В данном конкретном случае речь идет о регистраторах 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())