Is there an easy way to create a log instance for each class?

Now I use the static method to register (because it is very easy for me to log in to Android), but now I need to configure different applications for different classes, so I had a problem with static logging.

And I read Log4J: Strategies for creating Logger instances , I notice that it is time to change the logging strategy, so I will need the following code for my class, which needs a special logger.

private static final Logger logger = Logger.getLogger(XXXX.class); 

I feel like this is repetitive work, so are there any ways to avoid adding duplicate code for each individual class or just write less code. Can an AOP or an addiction injection perform such tasks?

I use log4j and Spring, but any other ways to do this would be much appreciated.

+4
java spring dependency-injection logging log4j
source share
4 answers

Yes you could.

  • Create your own personal annotation, say @Logger

     @Retention(RUNTIME)//will be used at runtime, so retain till runtime @Target(FIELD)//field level annotation public @interface Logger { } 
  • Annotate your Logger field as @Logger in beans, which is introduced by Spring.

     @Logger private Logger logger; 

    Here you can use slf4j logger, but it's up to you, since you can directly use log4j, etc. See how I recorded the annotated journal. This is in the bean that Spring creates.

  • Using the Spring Lifecycle Interface, called BeanPostProcessor, and in the postProcessBeforeInitialization method, which uses the utils reflection class, to input the registrar.

     public class LoggerInjector implements BeanPostProcessor { /** * Return the bean itself. */ public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { return bean; } /** * For all beans before initialization, inject the logger using slf4j. * @param bean * @param beanName * @return returns same bean by injecting logger. */ public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException { ReflectionUtils.doWithFields(bean.getClass(), new FieldCallback() { public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException { ReflectionUtils.makeAccessible(field); if (field.getAnnotation(Logger.class) != null) { if (field.get(bean) == null) { final Logger logger = LoggerFactory.getLogger(bean.getClass()); field.set(bean, logger); } } } }); return bean; } } 
  • Once you're done, let Spring know that you have a log injector:

     <bean id="loggerInjector" class="com.mypackage.LoggerInjector"/> 
+2
source share

It really is a "re-work" to add a logger to every class that needs it, however keep in mind that even with dependency injection you still need to declare a method variable ("logger" in your case). Thus, this will not save you from multiple entries.

I would also recommend using a journal facade, such as SLF4J , with a basic implementation, such as a magazine. The journal entry was written by the same author log4j, but is better for these reasons . If you chose this route (using SLF4J with your application), be sure to add jcl-over-slf4j to your class path (possibly in your pom file), since you are using Spring.

Again about logging strategies, it might be worth looking at the demo application listed in the logging documentation. Sample code similar to yours only using a logging facade:

 Logger logger = LoggerFactory.getLogger(LoginAction.class); 
0
source share

You can try with the Lombok project. You just need to add the lombok library to your classpath, and of course you will need the log4j libraries. and use the @Slf4j annotation at the class level, then you should be able to write log messages like this. log.info("message") without creating a static log instance.

more details here http://projectlombok.org/features/Log.html

0
source share

In your context, you can add a logger bean using the factory method for each logger you need (although this is not the usual way):

 <bean id="logger" scope="prototype" class="org.apache.log4j.Logger" factory-method="getLogger"> <constructor-arg name="name" value="youLoggerName" /> </bean> 

then you can simply enter your registrar:

 @Autowired private Logger logger; 
0
source share

All Articles