4 Replies Latest reply on Feb 17, 2006 5:17 AM by martplus

    EMBEDDED EJB with AOP

    martplus

      Hello everyone!

      I want to use Jboss-AOP within my embedded ejb testapplication. More conrete, I want to use it for my own dependency injections into stateless session beans...

      @Stateless
      public class MyBean implements MyLocal {
      @MyContext(name="shop")
      MyType pleaseInjectMe;

      ...


      whereas my Aspect class would look like that:
      @Aspect
      public class MyAspect {

      public MyAspect() {}

      @Bind (pointcut="field(MyType *->@MyContext )")
      public Object myAdvice(Invocation invocation) throws Throwable
      {
      return invocation.invokeNext();
      }
      }


      I prefer Annotations to XML, but I also would be happy to get my Embedded Sample running with XML-AOP definitions.

      Can anybody give me some hints for configuration? I tried out several things but my "myAdvice" method was never called within embedded ejb.


      Thanks in advance, Martin

        • 1. Re: EMBEDDED EJB with AOP
          bill.burke

          check out

          ejb3-interceptors-aop.xml

          Each container type (stateless, mdb, stateful) has its own aspect domain defined. You can create a constructor intercepting aspect that does the work. EJB3 does not instrument classes, it is proxy based, but built on top of JBoss AOP.

          Maybe you should consider using EJB3 interceptors to implement your injection annotation? They are portable between vendors. EJB3 interceptors allow you to intercept bean creation (@PostConstruct).

          For both the AOP way and EJB3 interceptor way, a good project to look at is the JBoss Spring integration library. See our wiki for more details.

          • 2. Re: EMBEDDED EJB with AOP
            martplus

            I checked already ejb3-interceptors-aop.xml out, but I only get callbacks for my business-methods (and not for field access).

            Spring was also an idea at the beginning of the project, but I try to keep the non-standard stuff limited to jboss things, otherwise I would have to study too much things ...

            Anyway, the @PostConstruct annotation is good enough for the moment. (Although I like the idea of dependency injection)

            Thank you again,

            Martin



            • 3. Re: EMBEDDED EJB with AOP
              bill.burke

              No, I'm saying you can intercept @PostConstruct within an EJB3 interceptor. Look for the injection annotations then perform the injection. Get me now? Again, look at the EJB3/Spring integration WIKI and code for more details.

              • 4. Re: EMBEDDED EJB with AOP
                martplus

                OK, I think I got it.

                For everybody who is interrested in this topic:

                I'm not using spring for my solution but extended the ejb3-interceptors-aop.xml:

                <interceptor class="at.csd.e3e.ejb3.annotations.SchemaContextInjector" scope="PER_VM"/>
                (...)
                <domain name="Stateless Bean">
                 <bind pointcut="execution(@javax.ejb.Stateless->new(..))">
                 <interceptor-ref name="at.csd.e3e.ejb3.annotations.SchemaContextInjector"/>
                 </bind>
                (...)
                


                The code for the Injector looks like this:
                package at.csd.e3e.ejb3.annotations;
                
                import java.lang.reflect.Field;
                
                import org.jboss.aop.joinpoint.Invocation;
                import org.jboss.aop.advice.Interceptor;
                
                import at.csd.e3e.ejb3.schema.SchemaDescriptionImplRegistry;
                
                public class SchemaContextInjector implements Interceptor {
                 public String getName() { return getClass().getName(); }
                
                 public Object invoke(Invocation invocation) throws Throwable {
                 Object newInstance = invocation.invokeNext();
                
                 Class clazz = newInstance.getClass();
                 for (Field f : clazz.getDeclaredFields()) {
                 SchemaContext anno = f.getAnnotation(SchemaContext.class);
                 if (anno != null) {
                 f.setAccessible(true);
                 f.set(invocation.getTargetObject(), SchemaDescriptionImplRegistry.SINGLETON.getSchemaDescription(anno.unitName()));
                 break;
                 }
                 }
                 return newInstance;
                 }
                }