Вот альтернатива вашему решению. Вы можете достичь своей цели с помощью BeanFactoryPostProcessor реализации.
Предположим, вы хотите иметь класс с ведением журнала. Вот оно:
package log;
import org.apache.log4j.Logger;
@Loggable
public class MyBean {
private Logger logger;
}
Как вы могли видеть, этот класс ничего не делает и создан для простоты как контейнер логгера. Единственная замечательная вещь здесь - это @ Loggable аннотация.
Вот его исходный код:
package log;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Loggable {
}
Эта аннотация является лишь маркером для дальнейшей обработки. И вот самая интересная часть:
package log;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import java.lang.reflect.Field;
public class LoggerBeanFactoryPostProcessor implements BeanFactoryPostProcessor{
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] names = beanFactory.getBeanDefinitionNames();
for(String name : names){
Object bean = beanFactory.getBean(name);
if(bean.getClass().isAnnotationPresent(Loggable.class)){
try {
Field field = bean.getClass().getDeclaredField("logger");
field.setAccessible(true);
field.set(bean, Logger.getLogger(bean.getClass()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Он просматривает все bean-компоненты, и если bean-компонент помечен как @ Loggable , он инициализирует свое личное поле с именем logger . Вы можете пойти еще дальше и передать некоторые параметры в аннотации @ Loggable . Например, это может быть имя поля, соответствующего регистратору.
Я использовал Log4j в этом примере, но я думаю, он должен работать точно так же, как и с slf4j.