9

I'm using non static loggers named according to class name:

protected Logger logger = LoggerFactory.getLogger(getClass());

Can I configure spring in a way, that will set proper logger using @Autowired?

@Autowired
protected Logger logger;

I can use factory-method for logger initialization, but I don't know how to pass the class name as an argument. For the setter-based dependency injection, spring has to know the class name, since it holds the reference to the bean. Can I access it somehow? Is there another way?

Kojotak
  • 2,020
  • 2
  • 16
  • 29

4 Answers4

18

In order to make Logger be injectable with @Autowired, you must have a configuration class where you have configured all the Beans with which you use @Autowired. That class will be marked with @Configuration. There you must put the following @Bean in your configuration:

@Configuration
public class WebConfiguration {

    @Bean
    @Scope("prototype")
    public Logger produceLogger(InjectionPoint injectionPoint) {
        Class<?> classOnWired = injectionPoint.getMember().getDeclaringClass();
        return LoggerFactory.getLogger(classOnWired);
    }
}
Javi M
  • 191
  • 1
  • 6
  • 3
    Great answer. Asking nicely......it is so much easier to figure these out when the java examples contain all the important import statements listed, without "*". – granadaCoder Oct 14 '19 at 13:06
  • 3
    For future readers: import org.springframework.beans.factory.InjectionPoint; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; import org.slf4j.Logger import org.slf4j.LoggerFactory; – granadaCoder Oct 14 '19 at 13:08
1

You can inject it with @Inject and BeanFactoryPostProcessor

@Inject
Logger logger;

You can find more details here: Using java annotation to inject logger dependency

Community
  • 1
  • 1
kozla13
  • 1,854
  • 3
  • 23
  • 35
  • I think that this is the correct answer. I have used spring's post processors for something else recently and from the backward perspective it is exactly what I was looking for. – Kojotak Jun 26 '14 at 07:04
0

You could do it with a @Qualifier annotation. Of course that means that you have added Logger objects to your application context already.

Importing this config into your application context would allow you to do that:

@Configuration
public class LoggerConfig {
    @Bean
    public Logger myClassLogger() {
        return LoggerFactory.getLogger(MyClass.class);
    }

    @Bean
    public Logger myOtherClassLogger() {
        return LoggerFactory.getLogger(MyOtherClass.class);
    }
}

And then in your classes that uses the Logger:

@Component
public class MyClass {
    @Autowired
    @Qualifier("myClassLogger")
    private Logger logger;

    //...
}

@Component
public class MyOtherClass {
    @Autowired
    @Qualifier("myOtherClassLogger")
    private Logger logger;

    //...
}
nicholas.hauschild
  • 42,483
  • 9
  • 127
  • 120
0

to use autowired logger as describe below:

package de.senatov.wflow.config;

import org.slf4j.Logger;

@Configuration
public class WebFlowConfig extends AbstractFacesFlowConfiguration {


    @Autowired
    private Logger log;



    @Bean
    public FlowDefinitionRegistry flowRegistry() {

        log.debug("flowRegistry()");
        return getFlowDefinitionRegistryBuilder(flowBuilderServices()).addFlowLocation("/WEB-INF/flows/booking/booking-flow.xml", "booking")
                                                                      .addFlowLocation("/WEB-INF/flows/main/main-flow.xml", "main").build();
    }
.....
.... 

1) insert small class:

package de.senatov.wflow.loggable;


import org.slf4j.Logger;
import org.springframework.beans.factory.InjectionPoint;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import static java.util.Optional.of;
import static org.slf4j.LoggerFactory.getLogger;

@Configuration
public class LoggingConfiguration {
    @Bean
    @Scope("prototype")
    public Logger logger(InjectionPoint ip) {

        try {
            return getLogger(of(ip.getMember())
                                     .map(o -> o.getDeclaringClass())
                                     .orElseThrow(IllegalArgumentException::new));
        }
        catch (Exception e) {
            System.err.printf("slf4j autowired Exception occured : %s%n", e.getMessage());
            throw e;
        }
    }
}
Iakov Senatov
  • 151
  • 1
  • 5