Customizing EJB3 Configuration
This example shows you how to customize EJB3, specifically how to customize the default configuration settings and the
default client and server interceptors. For example, we will see how you can modify such things as instance pool sizes
for stateless session beans and how to add custom behavior to beans via custom interceptors.
ejb3-interceptors-aop.xml
The majority of EJB3 configuration with the exception of such areas as cluster caches, remoting, and deployer configuration
is in the ejb3-interceptors-aop.xml file found in the deploy directory. If you are familiar with EJB2.1,
ejb3-interceptors-aop.xml is analagous to standardjboss.xml but uses JBoss's Aspect Oriented Programming mechanism.
standardjboss.xml is not used by EJB3.
First, take a look at the default ejb3-interceptors-aop.xml. Each of the sections will be
described individually.
Interceptors
The <Interceptor ... /> elements define the interceptors and interceptor factories to be used by the client and server configuration.
The scope of each is also defined, specifying how many interceptor instances will be created. Each interceptor or interceptor factory
must be defined.
Client Side Interceptors
The <stack .. /> elements are used to create an interceptor chain for the client (i.e. ejb proxy) side. The default chains
create standard client side behavior for the various types of beans.
Domains
The <domain ... /> elements configure the server side. There is a default domain for each bean type. This is where the server
side interceptor chains are defined using the AOP Pointcut Language (i.e. <bind pointcut="..." />). Please see the AOP
documentation for more information on the Pointcut Language. The Domains are also used to introduce default annotations and thus
create default behavior for each of the bean types. For example, take a look at the "Stateless Bean" domain. Notice that through the
<annotation expr="..." /> element, a default @org.jboss.annotation.ejb.PoolClass is created for each stateless session bean that
does not explicitly define a @org.jboss.annotation.ejb.PoolClass annotation on the class.
Customization of ejb3-interceptors-aop.xml
You may modify the default behavior via the interceptor chains and annotation introductions in ejb3-interceptors-aop.xml. Take a
look at the modified ejb3-interceptors-aop.xml. First, notice that we have defined a
org.jboss.tutorial.configuration.TeacherAopInterceptor interceptor and added this interceptor to the client side interceptor chain
in the "StatelessSessionClientInterceptors" stack. Second, notice that we have defined another interceptor,
org.jboss.tutorial.configuration.BadMathAopInterceptor and have added it to the server side interceptor stack in the
"Stateless Bean" domain. Note that this interceptor is only bound to the subtract methods of the beans. Third, notice that we
have changed the default @PoolClass annotation to use StrictMaxPool of size 10, as opposed to ThreadLocalPool of size 30. This becomes
the default stateless session bean pool configuration for all beans that do not explicitly define a @PoolClass annotation.
Custom Domains and Stacks
You may also create your own custom server Domains and client interceptor Stacks and reference those configurations via annotations
on the beans themselves. Take a look at the modified custom-ejb3-interceptors-aop.xml. We have
created a custom client stack and a custom server domain. We have added the TeacherAopInterceptor to the custom client stack. We have
removed several of the standard interceptors from the default stateless session domain (e.g. security, transactions, clustering),
bound BadMathAopInterceptor to the add method, and modified the @PoolClass to be StrictMaxPool with a size of 1.
Custom Behavior
The custom interceptors are added to the client and server chains of the two concrete extensions of
CalculatorBean.java. Take a look at the two concrete classes
CustomizedCalculatorBean.java and
CustomDomainCalculatorBean.java. The former uses the custom
default configuration from ejb3-interceptors-aop.xml. The latter uses the custom stack and domain
configuration from custom-ejb3-interceptors-aop.xml. Notice the @AspectDomain and @RemoteBinding
annotations reference the custom stack and domain names.
BadMathAopInterceptor catches and modifies the results from the bound
methods from the calculator. TeacherAopInterceptor logs a message when an incorrect result is caught on the client side.
The custom PoolClass configuration for CustomDomainCalculatorBean uses a pool size of 1. This in effect, makes the stateless bean stateful
and serializes access to the bean. See the results below.
Building and Running
To build and run the example, make sure you have ejb3.deployer installed in JBoss 4.x and JBOSS_HOME is set to that installation.
Unix: $ export JBOSS_HOME=<where your jboss 4.0 distribution is>
Windows: $ set JBOSS_HOME=<where your jboss 4.0 distribution is>
$ ant
$ ant run
run:
[java] Testing CustomDomainCalculatorBean ...
[java] Wrong Answer!!
[java] 1 + 1 != 3
[java] 1 - 1 = 0
[java] Saving 123 ...
[java] Recalling 123
[java] Recalling 123
[java] Recalling 123
[java] Recalling 123
[java] Recalling 123
[java] Recalling 123
[java] Recalling 123
[java] Recalling 123
[java] Recalling 123
[java] Testing CustomizedCalculatorBean ...
[java] Recalling 123
[java] 1 + 1 = 2
[java] Wrong Answer!!
[java] 1 - 1 != 1
[java] Saving 123 ...
[java] Recalling 123
[java] Recalling 0
[java] Recalling 0
[java] Recalling 0
[java] Recalling 0
[java] Recalling 0
[java] Recalling 0
[java] Recalling 0
[java] Recalling 0
[java] Recalling 0
Look in the console window:
16:10:44,609 INFO [BadMathAopInterceptor] *** Intercepting in BadMathAopInterceptor in public int org.jboss.tutorial.configuration.bean.CalculatorBean.add(int,int)
16:10:49,718 INFO [BadMathAopInterceptor] *** Intercepting in BadMathAopInterceptor in public int org.jboss.tutorial.configuration.bean.CalculatorBean.subtract(int,int)