Spring Inject Logger by Annotation Example

This tutorial: Spring Inject Logger by Annotation Example show you how to Inject a logger by Annotation.

Dependencies

We use slf4j logger interface and log4j logger implementation. Next add the spring dependencies to your project.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>com.memorynotfound.spring.core</groupId>
    <artifactId>inject-logger</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <url>http://memorynotfound.com</url>
    <name>SPRING - ${project.artifactId}</name>

    <properties>
        <slf4j.version>1.7.12</slf4j.version>
        <log4j.version>2.3</log4j.version>
        <spring.version>4.1.6.RELEASE</spring.version>
    </properties>

    <dependencies>
        <!-- logging interface -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

        <!-- Binding for Log4J -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        
        <!-- Log4j API and Core implementation required for binding -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>

        <!-- spring dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
    </dependencies>
    
</project>

Spring Java Configuration

We use Spring Java Configuration to configure our spring beans.

package com.memorynotfound;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.memorynotfound")
public class AppConfig {

}

Create @Log Annotation

Create a new @Log annotation.

package com.memorynotfound;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(FIELD)
@Documented
public @interface Log {
}

Spring Inject Logger by Annotation

We can use the @Log annotation at field level to describe that we want to inject a logger.

package com.memorynotfound;

import org.slf4j.Logger;
import org.springframework.stereotype.Component;

@Component
public class StepService {

    private static @Log Logger LOG;

    public void step(int steps){
        LOG.info("executing " + steps + " steps.");
    }
}

Create LogInjector

This is where the magic happens. We implement the BeanPostProcessor which gives us the postProcessBeforeInitialization method which allows us to manage a bean before initialization. We search for the @Log annotation and inject an implementation with the LoggerFactory.

package com.memorynotfound;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;

@Component
public class LogInjector implements BeanPostProcessor {

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessBeforeInitialization(final Object bean, String name) throws BeansException {
        ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
                // make the field accessible if defined private
                ReflectionUtils.makeAccessible(field);
                if (field.getAnnotation(Log.class) != null) {
                    Logger log = LoggerFactory.getLogger(bean.getClass());
                    field.set(bean, log);
                }
            }
        });
        return bean;
    }
}

Log4j2 properties

Add the log4j2.xml to your classpath.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns="http://logging.apache.org/log4j/2.0/config">

    <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
    </Appenders>

    <Loggers>
        <Logger name="com.memorynotfound" level="debug"/>

        <Root level="info">
            <AppenderRef ref="STDOUT"/>
        </Root>
    </Loggers>

</Configuration>

Bootstrap Application

Lets test our application. First we bootstrap spring configuration. Next we test the service.

package com.memorynotfound;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {

    public static void main(String...args){
    	ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
    	StepService stepService = context.getBean(StepService.class);

        stepService.step(1);
        stepService.step(2);
        stepService.step(3);
    }
}

Output

INFO  | 2015-06-23 21:16:58 | [main] memorynotfound.StepService (StepService.java:12) - executing 1 steps.
INFO  | 2015-06-23 21:16:58 | [main] memorynotfound.StepService (StepService.java:12) - executing 2 steps.
INFO  | 2015-06-23 21:16:58 | [main] memorynotfound.StepService (StepService.java:12) - executing 3 steps.

References

Download

You may also like...