Java 如何将记录器注入示例 Spring Boot 应用程序中的字段?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26517309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 02:41:07  来源:igfitidea点击:

How do I inject a logger into a field in the sample spring boot application?

javaspringloggingspring-bootautowired

提问by vic

What I want is to make spring autowire a logger. So, in other words, I want to have this working:

我想要的是让 spring 自动装配一个记录器。所以,换句话说,我想让这个工作:

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";
    }
}

Right now it throws an exception at startup: "No qualifying bean of type [org.slf4j.Logger] found for dependency...".

现在它在启动时抛出一个异常:“没有找到类型为 [org.slf4j.Logger] 的合格 bean 依赖......”。

My pom.xml dependencies:

我的 pom.xml 依赖项:

<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 this

我读了这个

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

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

It says if you use one of the starter poms (i do) Logback is used - but for internal logging. Can it be autowired in my classes?

它说,如果您使用启动器 poms 之一(我这样做),则使用 Logback - 但用于内部日志记录。它可以在我的课程中自动装配吗?

采纳答案by fl4l

Although it is not the usual way you can add a logger bean directly in your context reproducing the classic bind:

尽管这不是通常的方式,您可以直接在您的上下文中添加一个记录器 bean 来重现经典绑定:

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

simply inserting in the spring context:

只需在 spring 上下文中插入:

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

then you can simply inject your logger:

然后你可以简单地注入你的记录器:

@Autowired
private Logger logger;

回答by Andy Wilkinson

You canhave Spring autowire a Logger instance, but it would be a very unusual thing to do (you'd need a bean of type Loggerto be in your application context). The far more usual approach is to initialise the logger where it's declared, configuring it with the class that will be using it for logging:

可以让 Spring 自动装配 Logger 实例,但这将是一件非常不寻常的事情(您需要Logger在应用程序上下文中使用类型为bean 的 bean )。更常见的方法是在声明它的地方初始化记录器,使用将使用它进行记录的类配置它:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MainController {

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

}

回答by Simon Jenkins

If the objective here is code reduction then try Project Lombok. You then don't even need to declare the logger - just add an annotation and use loginstead of logger

如果这里的目标是减少代码,那么试试Project Lombok。然后你甚至不需要声明记录器 - 只需添加一个注释并使用log而不是logger

So your above code will now 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";
    }
}

回答by Dherik

Solutionusing @Bean:

解决方案使用@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 inject the Logger using Constructor Injection (field injection will not work):

之后,只需使用构造函数注入(字段注入不起作用)注入 Logger :

@Service
class SomeService {

    private Logger logger;

    public SomeService(Logger logger;) {
        this.logger = logger;
    }

    public void someMethod() {
        logger.error("Some log");
    }  
}

回答by bitsmonkey

This is how I got it working for field injection

这就是我让它用于场注入的方式

LoggingConfiguration.java

日志配置.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

虚拟控制器.java

@Controller
public class DummyController {

@Autowired
private Logger log;

//......