问题
I have a no-client application that I wish to run. It will have no clients but it will make HTTP calls and act as client for other services. It would run for perhaps a few hours or days (but it will not require periodic runs -- just one-shot).
I want to run it in a Java EE 7 container, because of the benefits of standard Context Dependency Injection (CD), and a standard JAX-RS client (new since Java EE 7). It is also nice to have services such as JMS, JPA.
The question is how do I write / annotate the main method in a standard way? @Inject
on a method is no good because such methods must return quickly. @Schedule
is not ideal because it runs periodically unless I programmatically determine current system time.
The best I could come up with is to set a one-shot Timer
in an @Inject
method and annotate my main method with @Timeout
.
Somehow this seems a bit fragile or inelegant. Is there a better standard way to start the service? Some annotation that would just cause it to start and get going?
Additionally, how what is the best standard way to interrupt and shut down the service upon undeployment?
回答1:
If you can use the EJB
with(or instead of) CDI
, then try the @Singleton
+ @Startup
annotations for your bean, and @PostConstruct
for your main()
method.
@Singleton
@Startup
public class YourBean {
@Stateless
public static class BeanWithMainMethod{
@Asynchronous
public void theMainMethod(){
System.out.println("Async invocation");
}
}
@EJB
private BeanWithMainMethod beanWithMainMethod;
@PostConstruct
private void launchMainMethod(){
beanWithMainMethod.theMainMethod();
}
}
回答2:
When PostConstruct is long running, decouple with events:
@Singleton
@Startup
public class YourBean{
@Inject
private Event<XXX> started;
@PostConstruct
private void theMainMethod(){
started.fire(new XXX());
}
public void handleStarted(@Observes XXX started) {
// the real main method.
}
}
来源:https://stackoverflow.com/questions/16491243/how-to-write-main-using-cdi-in-java-ee