Seasar2 is a light weight container for Dependency Injection (DI) operations, and also implements EJB3.
Let us give this a try. The following objects will be used.
- Greeting class
- Returns a greeting string.
- Greeting Client Class
- Outputs string obtained from the greeting class to console.
- Greeting Main Class
Greeting.java
Greeting interface.
package examples.ejb3;
public interface Greeting {
String greet();
}
GreetingImpl.java
Implementation of the greeting. We can make a stateless session bean using the Stateless annotation.
package examples.ejb3.impl;
import javax.ejb.Stateless;
import examples.ejb3.Greeting;
@Stateless
public class GreetingImpl implements Greeting {
public String greet() {
return "Hello World!";
}
}
GreetingClient.java
Client interface to use the greeting.
package examples.ejb3;
public interface GreetingClient {
void execute();
}
GreetingClientImpl.java
Client implementation to use the greeting. We can refer the session bean implementing the greeting interface using the EJB annotation.
package examples.ejb3.impl;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import examples.ejb3.Greeting;
import examples.ejb3.GreetingClient;
@Stateless
public class GreetingClientImpl implements GreetingClient {
@EJB
private Greeting greeting;
public void execute() {
System.out.println(greeting.greet());
}
}
GreetingMain.dicon
Configration file for EJB3. If we define this content from the beginning, it's not necessary to add any information to the configuration file, even if the number of EJB increases. Please refer component auto-registration in the details.
<components> <include path="ejb3tx.dicon"/> <component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister"> <initMethod name="addClassPattern"> <arg>"examples.ejb3.impl"</arg> <arg>".*Impl"</arg> </initMethod> </component> </components>
GreetingMain.java
The source code to run Seasar2 EJB3 is as follows. Please refer S2Container creation about SingletonS2ContainerFactory. Please refer DefaultAutoNaming about the naming rule in case we don't specify the name property of @EJB.
package examples.ejb3.main;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import examples.ejb3.GreetingClient;
public class GreetingMain {
private static final String PATH = "examples/ejb3/dicon/GreetingMain.dicon";
public static void main(String[] args) throws Exception {
SingletonS2ContainerFactory.setConfigPath(PATH);
SingletonS2ContainerFactory.init();
try {
doMain(args);
} finally {
SingletonS2ContainerFactory.destroy();
}
}
public static void doMain(String[] args) throws Exception {
Context ctx = new InitialContext();
GreetingClient greetingClient = (GreetingClient)
ctx.lookup("greetingClient");
greetingClient.execute();
}
}
The result will be as follows:
DEBUG 2006-03-25 18:38:47,892 [main] Transaction began
Hello World!
DEBUG 2006-03-25 18:38:47,922 [main] Transaction committed
S2Container supports EJB 3.0 Simplified API. We need Java5 in order to use the EJB3 annotation.
We can define a stateless session bean using Stateless annnotaion.
Tiger annotation is as follows.
@Stateless(name="xxx")
public class Xxx {
...
}
When we don't specify the name property, the implementation class of AutoNaming interface which we use the automatic registration of components will automatically deside the name.
We can define a stateful session bean using Stateful annnotaion.
Tiger annotation is as follows.
@Stateful(name="xxx")
public class Xxx {
...
}
When we don't specify the name property, the implementation class of AutoNaming interface which we use the automatic registration of components will automatically deside the name.
The EJB annotation denotes a reference to a session bean. The beanName property references the value of the name property of the Stateful or Stateless annotation. The beanName property allows disambiguation if multiple session beans implement the same interface.
Tiger annotation is as follows.
@EJB
public void setAaa(Aaa aaa) {
...
}
@EJB(beanName="bbb2")
public void setBbb(Bbb bbb) {
...
}
We can use "Container Management Transaction(CMT)" and "Bean Management Transaction(BMT)" using the TransactionManagement annotation. The default is CMT, therefore we don't need to specify the TransactionManagement annotation using CMT.
Tiger annotation is as follows.
@Stateless
@TransactionManagement(TransactionManagementType.BEAN)
public class Xxx {
...
}
If we use CMT, we can specify transaction attribute for business method using the TransactionAttribute annotation. The default is REQUIRED. If we sepcify the TransactionAttribute annotation for a class, we can specify its annotation for all the business methods of the class. If we sepcify the TransactionAttribute annotation for a method, we can specify its annotation for the business method.
Tiger annotation is as follows.
@Stateless
@TransactionAttribute(TransactionAttributeType.MANDATRY)
public class Xxx {
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void someMethod() {
...
}
}
We can specify several interceptors for the invocation of business methods and the lifecycle methods using the Interceptors annotation.
We can specify interceptors annotation for class or method.
@Stateless
@Interceptors({foo.bar.HogeInterceptor.class, foo.bar.SomeInterceptor})
public class Xxx {
...
@Interceptors(foo.bar.MethodInterceptor)
private void hogehoge() {
...
}
}
When the ExcludeDefaultInterceptors annotation applied to a business method, it excludes the invocation of default interceptors for that method.
@Stateless
@Interceptors(foo.bar.HogeInterceptor.class)
public class Xxx {
...
@ExcludeClassInterceptos
@Interceptors(foo.bar.MethodInterceptor)
private void hogehoge() {
...
}
}
We can specify the method invoked after an instance creation and DI using the PostConstruct annotation. We can specify the PostConstruct annotation for a sesssion bean or a method of a interceptor. Lifecycle callback methods defined on a bean class have the following signature: public void <METHOD>()
Lifecycle callback methods defined on an interceptor class have the following signature: public void <METHOD>(InvocationContext)
Tiger annotation is as follows.
@Stateless
@Interceptors(Yyy.class)
public class Xxx {
...
@PostConstruct
public void initialize() {
...
}
}
public class Yyy {
...
@PostConstruct
public void initialize(InvocationContext context) {
...
}
}
We can intercept invocations of business method using the AroundInvoke annotation. We can specify AroundInvoke annotation for a session bean and the method of interceptor. The method with the AroundInvoke annotation must be no static, no final, and the type of argument must be javax.interceptor.InvocationContext, and the type of return must be Object. We can specify the AroundInvoke annotation for only one method.
Tiger annotation is as follows.
@Stateless
@Interceptors(Yyy.class)
public class Xxx {
...
@AroundInvoke
Object invoke(InvocationContext context) throws Exception {
...
}
}
public class Yyy {
...
@AroundInvoke
private Object invoke(InvocationContext context) throws Exception {
...
}
}
|