1 Reply Latest reply on Aug 28, 2012 5:49 AM by Martin Kouba

    Can I automatically transform beans after they're constructed? - perhaps an interceptor around whenever any object is constructed?

    Steven Boscarine Apprentice

      Hello All,

      I am trying to build a general purpose configuration binding library for my employer.  Our old system manually grabbed values from properties files in the consuming code via static methods...very ugly.  I want something that decouples the consumer and producer of this data as we're going to move away from simple properties files to more possible sources.

       

      Does anyone know of examples I can look at to determine how to invoke my custom code across CDI beans when they're first contructed? Here's what I am trying to do:

       

      Step 1:  User puts my annotation around on a field or method for a configuration bean to bind a string key to a field my custom logic will use.

      @ApplicationScoped
      public class ThreadPoolSettings{
           @Config("foo.bar.numThreads")     
           int numberOfThreads;
           @Config("foo.bar.timout")
           long timeout;
      }
      

       

      Step 2:  User injects bean into consumers

      public class ThisClassUsesThreads{
           @Inject
           ThreadPoolSettings settings;
      }
      

      ..same object is injected into multiple classes w/o any knowledge of my framework.

      public class ThisClassAlsoUsesThreads{

           @Inject

           ThreadPoolSettings settings;

      }


      I'd like to write an engine where the user doesn't need to do anything else...just write valid CDI code, add my annotations to fields and methods and have the system transform the default values into values looked up by my custom code.

       

      Runtime:

      1. CDI Container constructs ThreadPoolSettings to inject into those fields.
      2. Some sort of generic interceptor is called across all classes constructed by CDI (I'd have it enabled in beans.xml)
      3. In my "interceptor," I write reflection code to check for my special annotation.  (I managed to write everything but the interceptor)
      4. If my special annotation is there, I run my special class to inject whatever value is represented by that key. (already written)
      5. The transformed bean is injected into the consumer and no one is the wiser.
      6. All scopes are respected and logic is bound only to when the bean is constructed, so since the setting is @ApplicationScoped, my values are injected only when that bean is constructed...only once, despite being injected into 2 consumers.
      7. No consuming classes are aware of my config framework and just use "vanilla" CDI and can be tested without knowledge of what my framework does.

       

      Is this possible?

       

      What should I look for regarding this interceptor-like functionality?  I saw a lot of @AroundInvoke stuff, but didn't see any examples in the documentation that use:

      public class DependencyInjectionInterceptor {
          @PostConstruct 
          public void injectDependencies(InvocationContext ctx) { ... }
       }
      

      ...and I got errors trying to enable that interceptor code above, but was just taking wild guesses as to how it is meant to work.  Am I barking up the wrong tree here?

       

      Are there examples somewhere I can look for?

       

      Thanks in advance!!!

      Steven