It is tedious to write every time
Logger log = LogManager.getLogger(getClass());
To speed up one can copy this string from one class to another.
Not very expressive way. Well, it is more code to read.
Nowadays we have annotations, we have EJB, we have CDI.
We can improve the logging code in two ways:
- implement the logging as a cross-cutting concern with a CDI interceptor
- if we need more logging it would be much simpler to inject logger
import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; import org.apache.commons.lang3.builder.ReflectionToStringBuilder; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @Logable @Interceptor public class LoggingInterceptor { @AroundInvoke public Object log(InvocationContext ctx) throws Exception { Logger logger = LogManager.getLogger(ctx.getTarget().getClass() .getName()); Object[] args = ctx.getParameters(); logger.info("enter " + ctx.getMethod() + " : " + ReflectionToStringBuilder.toString(args)); Object returnMe = ctx.proceed(); logger.info("exit " + ctx.getMethod() + " returned " + ReflectionToStringBuilder.toString(returnMe)); return returnMe; } }
Let's implement the Logable annotation:
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.interceptor.InterceptorBinding; @InterceptorBinding @Retention(RUNTIME) @Target({ TYPE, METHOD }) public @interface Logable { }
import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class LogFactory { @Produces Logger createLogger(InjectionPoint injectionPoint) { String name = injectionPoint.getMember().getDeclaringClass().getName(); return LogManager.getLogger(name); } }
Here is how can we use the code:
@ApplicationScoped @Logable public class ConnectionFactory implements IConnectionFactory { @Inject private Logger log; }
With just one annotation we have ease out life and typing boiler plate code of enter and exit from method.
Happy coding!
Комментариев нет:
Отправить комментарий