How to insert a registrar into a field in an example spring boot application?

I want to make spring autowire logger. So, in other words, I want this to work:

import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class MainController { @Autowired private Logger logger; @RequestMapping("/") public String enterSite(HttpServletResponse response) { logger.info("site entered"); return "welcome"; } } 

He is currently throwing an exception at startup: "No qualified bean of type [org.slf4j.Logger] found for dependency ..." was found.

My pom.xml dependencies:

 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.2.0.M1</version> <relativePath /> <!-- lookup parent from repository --> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>9.1-901.jdbc4</version> </dependency> <!-- <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> --> </dependencies> 

I read it

http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-logging

It says that if you use one of the starting priests (I do), the log is used, but for internal logging. Can it be auto-magnified in my classes?

+12
source share
5 answers

Although this is not an ordinary way, you can add a logger bean directly to your context, reproducing the classic binding:

 private final Logger logger = LoggerFactory.getLogger(MainController.class); 

just pasting spring into the context:

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

then you can simply enter your registrar:

 @Autowired private Logger logger; 
+11
source

If the goal here is to shorten the code, try Project Lombok . Then you don’t even have to declare a registrar - just add an annotation and use log instead of logger

So your previous code would look like this:

 import javax.servlet.http.HttpServletResponse; import org.slf4j.Logger; // import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import lombok.extern.slf4j.Slf4j; @Slf4j @Controller public class MainController { @RequestMapping("/") public String enterSite(HttpServletResponse response) { log.info("site entered"); return "welcome"; } } 
+19
source

You might have a Spring autowire instance of Logger, but that would be very unusual (you need a Logger bean in your application context). A more common approach is to initialize the registrar where it was declared by setting it to a class that will use it for logging:

 import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MainController { private final Logger logger = LoggerFactory.getLogger(MainController.class); } 
+6
source

Solution using @Bean :

 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.InjectionPoint; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; @Configuration public class LoggerConfiguration { @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public Logger logger(InjectionPoint injectionPoint){ return LoggerFactory.getLogger(injectionPoint.getMethodParameter().getContainingClass()); } } 

After that, just enter Logger using Constructor Injection ( inserting a field will not work ):

 @Service class SomeService { private Logger logger; public SomeService(Logger logger;) { this.logger = logger; } public void someMethod() { logger.error("Some log"); } } 
+3
source

Here's how I got it working for field injection

LoggingConfiguration.java

 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class LoggingConfiguration { @Bean public Logger log() { var log = LoggerFactory.getLogger("com.bitsmonkey.dummy"); return log; } } 

Now inside the controller

Dummycontroller.java

 @Controller public class DummyController { @Autowired private Logger log; //...... 
0
source

Source: https://habr.com/ru/post/977102/


All Articles