web-dev-qa-db-ja.com

サンプルスプリングブートアプリケーションのフィールドにロガーを注入するにはどうすればよいですか?

私が欲しいのは春のオートワイヤーをロガーにすることです。つまり、言い換えれば、これを機能させたいのです。

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

現在、起動時に例外が発生します:「依存関係のタイプ[org.slf4j.Logger]の修飾Beanが見つかりません...」。

私の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>

私はこれを読んだ

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

スターターポン(i do)の1つを使用する場合は、Logbackが使用されますが、内部ロギング用です。クラスで自動配線できますか?

14
vic

通常のバインドを再現するコンテキストにロガーBeanを直接追加できる通常の方法ではありませんが、

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

単に春のコンテキストに挿入する:

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

その後、ロガーを注入するだけです:

@Autowired
private Logger logger;
12
fl4l

ここでの目的がコード削減である場合は、 Project Lombok を試してください。その後、ロガーを宣言する必要さえありません。注釈を追加して、logの代わりにloggerを使用してください

したがって、上記のコードは次のようになります。

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";
    }
}
22
Simon Jenkins

あなたはcan SpringにLoggerインスタンスを自動ワイヤリングさせていますが、これは非常に珍しいことです(アプリケーションコンテキストにLoggerのBeanが必要です)。はるかに一般的なアプローチは、ロガーを宣言した場所で初期化し、ロギングに使用するクラスで構成することです。

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

public class MainController {

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

}
6
Andy Wilkinson

ソリューション@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());
    }

}

その後、コンストラクター注入を使用してロガーを注入するだけです(フィールド注入は機能しません):

@Service
class SomeService {

    private Logger logger;

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

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

これは、フィールドインジェクションで機能させる方法です

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

コントローラーの中に

DummyController.Java

@Controller
public class DummyController {

@Autowired
private Logger log;

//......
0
bitsmonkey