I want to have a Stateless session bean in JAKARTA EE9 where I print "hello" on the console every 10 seconds. This is achieved by the following code.
@jakarta.ejb.Stateless(name = "MyTimerEJB")
public class MyTimerBean {
@Schedule(hour ="*", minute = "*", second = "*/10")
public void printTime() {
System.out.println("good day");
}
}
But now, I also want to add an interceptor that intercepts this on saturdays and sundays and then prints "good weekend". I've tried a bunch of things, but nothing seems to be working. The documentation is also a little bit limited unfortunately.
If you check out the EJB specs, section 7.4, you will find about the
AroundTimeoutannotation.In short, all you need is a normal, enabled interceptor for the bean you are interested in, with a method annotated with
@AroundTimeout.Having said that, I hope that the use case you describe is only an example. As a matter of fact I find it bad practice to use an interceptor to change the behavior of the program as radically as you describe. I would find it very hard to reason about the functionality of such a program. Interceptors are good to implement cross-cutting concerns (e.g. transactions, logging, authorization) that do not mess with the core logic of the intercepted code.
If I were to implement this use case I would:
SayHellobean that can knows how to decide what message to output depending on the day (or whatever)SayHello, nothing moreSince it proved to be useful, I am briefly re-iterating the main points of the JEE tutorial on interceptors:
WARNING: the following is a brief summary, please follow the tutorials and documentation for concrete usage
To define an interceptor, use one of the interceptor metadata annotations:
javax.interceptor.AroundConstruct,javax.interceptor.AroundInvoke,javax.interceptor.AroundTimeout,javax.annotation.PostConstruct,javax.annotation.PreDestroyon a method defined on a component that the container will recognize. Could be the same component as the one containing the intercepted method or a different one.If the interceptor is in a different class, use
javax.interceptor.Interceptorsto activate it. This annotation can go to a specific method, or on an entire class, in which case all business methods are intercepted. Remember, interceptors do not take effect on non-business methods (private/protected ones are definitely NOT business and a common mistake). Interceptors do NOT take effect when business calling methods ofthisobject, another very common mistake, beware!Alternatively you can define an interceptor binding annotation, e.g. (from the tutorial):
Now annotating a class or method with
@Loggedwill activate the interceptor defined as:To actually activate the interceptor you have to use the deployment descriptor (depending on whether you are using it on EJB or CDI or both) or use the
@Priorityannotation.