I wanted to create a LoggingInterceptor for my current Stack:
- Tomcat 8.5.24
- Weld 2.4.5-Final
- JSF 2.3.3
Here is the Annotation to mark methods or types for interception.
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.enterprise.util.Nonbinding;
import javax.interceptor.InterceptorBinding;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@InterceptorBinding
public @interface Logging {
@Nonbinding
Level value() default Level.TRACE;
public enum Level {
NONE, ALL, TRACE, DEBUG, INFO, WARN, ERROR;
}
}
Here is the Interceptor logic:
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
@Interceptor
@Logging
public class LoggingInterceptor {
@AroundInvoke
public Object interceptBusiness(final InvocationContext invocationContext) throws Exception {
Logger log = LoggerFactory.getLogger(invocationContext.getMethod().getDeclaringClass().getName());
log.trace("LOG start of method");
Object result = invocationContext.proceed();
log.trace("LOG end of method");
return result;
}
}
A simplified Bean:
import javax.annotation.PostConstruct;
import javax.inject.Named;
import javax.inject.Inject;
import javax.faces.view.ViewScoped;
@Named
@ViewScoped
@Logging(Level.DEBUG)
public class ListController implements Serializable {
private static final long serialVersionUID = 1L;
@Inject
EntityService entityService;
private List<Entity> entityList;
public List<Entity> getEntityList() {
return this.entityList;
}
public void setEntityList(final List<Entity> entityList) {
this.entityList= entityList;
}
public String doSomething(){
List<Entity> entityList = new ArrayList<>();
this.setEntityList(entityList);
return "";
}
@PostConstruct
public void setUp() {
this.setEntityList(this.entityService.findAll());
}
}
My interceptor for business methods works like a charm if called during runtime for example when pressing a button in the jsf view which calls the doSomething()
method. Both the doSomething()
and the setEntityList()
methods will be logged.
But all methods which are called in the @PostConstruct
method are not logged at all. That means the setEntityList()
method is not logged when called in the @PostConstruct
method.
Is there anything I can do to get the methods called from the @PostConstruct
method to be logged. I would appreciate some help. Thanks in advance.
Update due to the answer of HRgiger:
I also tried the @PostConstruct
method in my interceptor logic but with this method I can only log the invocation of the @PostConstruct
itself but the methods called in the @PostConstruct
method are not logged and that is still my main problem.
@PostConstruct
public void interceptLifecycle(final InvocationContext invocationContext) throws Exception {
Logger log = LoggerFactory.getLogger(invocationContext.getTarget().getClass().getSimpleName());
log.info("LOG start of POSTCONSTRUCT");
invocationContext.proceed();
log.info("LOG end of POSTCONSTRUCT");
}