JavaEE 5, Spring 2 and AspectJ 5: dependecy injection magics


After the Filippo disillusion about Java EE 5 dependecy injection I decided to study the problem of integrating dependecy injection capabilities provided by Java EE 5 and those provided by the Spring framework.


The challange is the following: let's assume that a Stateless EJB, let's say "TestEJB", needs the injection of two POJOs, let's say "TestBean1" and "TestBean2", using two different policies: using JNDI (via @Resource annotation) or without JNDI.


The test EJB and the two test beans implements the following interface:



@Local @Remote
public interface Test {
        public abstract String doTest();
}


The two beans just print out a message and return it; let's show TestBean1 (TestBean2 is similar)



public class TestBean1 implements Test {
        public String doTest() {
                String message = "=>TestBean1";
                System.out.println(message);
                return message;
        }
}


Now let's assume that the TestEJB needs to be injected of instances of TestBean1 and TestBean2 in order to print out and return a message partially composed by TestBean1 and TestBean2:



@Stateless
public class TestEJB implements Test {
        public String doTest() {
                String message = "=>TestEJB";
                System.out.println(message);
                return message + "(" + testBean1.doTest() + "," + testBean2.doTest()

+")";
        }
        
        @Resource(name="beans/TestBean1")
        private Test testBean1;
        
        private Test testBean2;

        public void setTestBean2(Test testBean2) {
                this.testBean2 = testBean2;
        }
}


In order to allow the injection of TestBean1 into TestEJB I found the following solution: let's assume that TestBean1 is defined in the Spring application context as follows:



        <bean id="TestBean1" class="test.TestBean1" />


Now let's populate the JNDI with entries that allow the instantiation of test beans using Spring. I used the following class:



public class SpringBeanFactory implements ObjectFactory {
        private static ApplicationContext appContext;

        private static final String BIND_NAME_PREFIX = "beans/";

        public static void populateJNDI(ApplicationContext appCtx) {
                appContext = appCtx;
                try {
                        Context ctx = new InitialContext();
                        String beansDef[] = appCtx.getBeanDefinitionNames();
                        for (int i = 0; i < beansDef.length; i++) {
                                Class beanClass = appCtx.getType(beansDef[i]);
                                String bindName = BIND_NAME_PREFIX + beansDef[i];
                                Reference reference = new Reference(beanClass.getName(),

new StringRefAddr(bindName,beansDef[i]),
                                                SpringBeanFactory.class.getName(), null);
                                ctx.rebind(bindName, reference);
                        }
                } catch (Exception e) {
                        throw new RuntimeException("Unable to populate JNDI from

application context", e);
                }
        }

        public Object getObjectInstance(Object reference, Name name, Context nameCtx,

Hashtable environment)
                        throws Exception {
                String beanName = (String) ((Reference) reference).get(0).getContent();
                return appContext.getBean(beanName, Object.class);
        }
}


The method "populateJNDI" needs to be invoked with the Spring ApplicationContext instance, for example in the "init" method of a Servlet:



public class TestServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;

        public TestServlet() {
                super();
        }

        @Override
        public void doGet(HttpServletRequest req, HttpServletResponse res) throws

ServletException, IOException {
                StringBuffer buf = new StringBuffer();
                buf.append("<html>");
                buf.append("<body>");
                buf.append("Hello from Servlet");
                buf.append("<br/>");
                buf.append("Hello from chain: ");
                buf.append(testEJB.doTest());
                buf.append("</body>");
                buf.append("</html>");


                res.getOutputStream().write(buf.toString().getBytes());
        }
        
        public void init(ServletConfig config) throws ServletException {
                super.init(config);
                ApplicationContext c =

WebApplicationContextUtils.getRequiredWebApplicationContext(config.getServletContext());
                SpringBeanFactory.populateJNDI(c);
        }

        @EJB
        protected Test testEJB;
}


That's all, the TestBean1 is avaiable for injection to EJBs using the @Resource(name="beans/TestBean1") annotation.


Now the second problem: I want to inject TestBean2 into TestEJB without registering the the bean into JNDI.


The solution uses Spring 2 integration with AspectJ. Let's assume that in the Spring application context is defined the following:



        <aop:spring-configured/>
        
        <bean id="TestEJB" class="test.TestEJB" lazy-init="false">
                <property name="testBean2">
                        <bean name="TestBean2" class="test.TestBean2"/>
                </property>
        </bean>


Now let's add a Spring2 @Configurable annotation to TestEJB:



@Stateless
@Configurable("TestEJB")
public class TestEJB implements Test {
        ...
}


That's all, by compiling the TestEJB with AspectJ using the "spring-aspects.jar" aspect library provided by Spring2, the TestBean2 will be injected into TestEJB.

( Jan 27 2006, 06:01:20 PM CET ) Permalink Comments [1]


Trackback URL: http://jroller.com/trackback/malbari/Weblog/javaee_5_spring_2_and
Posted by 아름프로
BLOG main image

카테고리

분류 전체보기 (539)
이야기방 (19)
토론/정보/사설 (16)
IBM Rational (9)
U-IT (0)
SOA/WS/ebXML (110)
개발방법론/모델링 (122)
J2SE (34)
J2EE (60)
DataBase (39)
Open Projects (30)
BP/표준화 (50)
Apache Projects (15)
Web/보안/OS (22)
Tools (7)
AJAX/WEB2.0 (1)
Linux/Unix (1)
영어 (0)
비공개방 (0)

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

달력

«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

글 보관함

Total :
Today : Yesterday :