4 Replies Latest reply on Aug 30, 2013 9:36 AM by synclpz

    Bean @Property injection

    synclpz

      Imagine we have a bean implementation which involves property usage, specified in switchyard.xml component/composite properties.

      It looks like this at the moment:

       

      @Service(SomeService.class)
      public class SomeServiceImpl implements SomeService {
      
           @Property(name = "string-property")
           String stringProperty;
      
           @Property(name = "int-property")
           String intProperty; //could be only String, but is integer semantically!
      
           public void someServiceMethod() {
                // there we should do
                int intPropValue = 0;
               try {
                     intPropValue = Integer.parseInt(intProperty);
                } catch (Throwable t) {
                     intPropValue = SOME_DEFAULT_FOR_EXAMPLE;
                }
           }
      }
      

       

      This is not a good way, because properties are set only while deployment, but should be parsed (integer is simple examle, but there could be more complex) any time service is invoked.

      I tried to achieve reading properties upon deployment via @PostConstruct

       

      @Service(SomeService.class)
      public class SomeServiceImpl implements SomeService {
           @Property(name = "string-property")
           String stringProperty;
      
           @Property(name = "int-property")
           String intProperty; //could be only String, but is integer semantically!
           int intPropValue;
      
           
           @PostConstruct
           void init() {
               try {
                     intPropValue = Integer.parseInt(intProperty);
                } catch (Throwable t) {
                     intPropValue = SOME_DEFAULT_FOR_EXAMPLE;
                }
           }
      
           public void someServiceMethod() {
                //just use intPropValue
           }
      }
      

      But no success, because it seems like they are injected after @PostConstruct.

       

      So, the questions are:

       

      1. Why not inject properties before @PostConstruct? They are not changing while bean is being invoked.

      2. Are there any methods of extracting implementation configuration parameters anywhere but properties supported internally in SY?

       

      Now I resolve this issue by using code:

       

      @Service(SomeService.class)
      public class SomeServiceImpl implements SomeService {
      
      
           @Property(name = "string-property")
           String stringProperty;
      
      
           @Property(name = "int-property")
           String intProperty; //could be only String, but is integer semantically!
         
        int intPropValue;
         
        private boolean init = false;
         
        private void init() {     
               try {
                     intPropValue = Integer.parseInt(intProperty);
                } catch (Throwable t) {
                     intPropValue = SOME_DEFAULT_FOR_EXAMPLE;
                }
              init = true;
        }
      
      
           public void someServiceMethod() {
            if (!init) {
                  init()
             }
           }
      }
      
        • 1. Re: Bean @Property injection
          kcbabo

          Hey Viktor,

           

          1. Why not inject properties before @PostConstruct? They are not changing while bean is being invoked.

          It's been a while since I've been in that code, but just refreshed my memory. :-)  The issue here is that CDI discovery and lifecycle events are independent from SY deployment.  The way it works now is that our CDI extension wires into the CDI lifecycle to find service beans, create proxies for references, and stash metadata on the side.  This metadata is then picked up during the service activation lifecycle in SY to wire up bean proxies to SY services and inject properties.  The upshot of this is that service wiring and property injection are not available in @PostConstruct and unless we change the way we integrate with CDI it's likely to stay that way.  I suppose we could parse switchyard.xml in our CDI extension and handle property injection at that point, but this still wouldn't address the reference wiring issue.

           

          If type-awareness is important for properties, I think it will be more straightforward to simply update the injection logic to look at the type of the field using property injection and attempt a conversion.  This would work with our current CDI integration and still happens "behind the scenes" so you don't have to go through gymnastics in your service logic to convert fields at runtime.

           

          2. Are there any methods of extracting implementation configuration parameters anywhere but properties supported internally in SY?

           

          That's the only supported way to do it right now. 

           

          cheers,

          keith

          • 2. Re: Bean @Property injection
            synclpz

            That's bad news.

             

            I picked a demo with "type-awareness" just for example. I meant there could be more complex logic, like opening connections to DB/or some reference system, initializing cache, some atomics etc.

            So, if property is not the way at the moment, I think we'll stay with some separate properties or xml file in META-INF and read it in @PostContruct.

             

             

            EDIT: May be implement some "@PostActivation" method on bean to make it properly set up before first service invocation? It could be called by activator...

            • 3. Re: Bean @Property injection
              kcbabo

              Agree with your comment regarding an event which correlates to completed initialization.  Another user raised this issue in the past as well.  We're not going to be able to get this in for 1.1, but we can definitely look at it for the next release.  Would you mind filing a JIRA?

               

              SwitchYard - JBoss Issue Tracker

               

              IIRC, where this conversation left off last time is that we would produce an event in the SY runtime which could then be bridged into CDI events.  So you could just implement a method with @Observes to act once initialization is fully completed.

               

              thanks,

              keith