Dependency Injection Performance in Java EE 6: Dependent (easy) vs ApplicationScoped ("optimized") 📎
public class Bean {
public long get() {
return System.currentTimeMillis();
}
}
@Path("application")
@Stateless
public class ApplicationScopeTester {
@Inject
ApplicationScopedBean bean;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String get(){
return String.valueOf(bean.get());
}
}
@ApplicationScoped
public class ApplicationScopedBean extends Bean{}
...and dependent scoped:
@Path("dependent")
@Stateless
public class DependentScopeTester {
@Inject
DependentScopedBean bean;
@GET
@Produces(MediaType.TEXT_PLAIN)
public String get(){
return String.valueOf(bean.get());
}
}
public class DependentScopedBean extends Bean {}
The test was performed with JMeter with the following settings:
500000 Samples, 5 Threads, no think time, with attached VisualVM. The results are interesting. The performance of the ApplicationScoped bean is only 3.5% better. In most measurements the performance was identical and around 3300 - 3500 transactions / second. Each request was handled by a Stateless Session Bean without any configuration, so each method invocation initiated a new transaction.
The reason for this result is the Stateless Session Bean and its pooling behavior. In Java EE 6 a Stateless Session Bean as a boundary / facade is not only the simplest, but also a reasonable choice. There was no difference in GC behavior, or CPU usage: CPU Usage 50%, GC Activity 7%, RAM usage 70 MB
Scope | Average | Min | Max | Transactions/Sec |
---|---|---|---|---|
Dependent | 1 | 0 | 95 | 3248.96 |
ApplicationScoped | 1 | 0 | 20 | 3366.41 |
The tests were performed with JDK 1.6 Glassfishv3.1 RC2 without any modifications. The entire projects with JMeter load script was pushed into: http://kenai.com/projects/javaee-patterns/, project DependentVsApplicationScopePerformance.
[Thanks Mark Struberg for the idea for this post!]