3 Replies Latest reply on Sep 28, 2011 3:07 AM by galder.zamarreno

    How to re-autowire/inject transient fields from Spring/IoC during deserialization?

    johncommon

      Hi,

       

      We are using Infinispan v4.2.1 as the low-level distributed cache for our Jetty HTTP sessions. We've developed an implementation of the Jetty

      AbstractSessionManager for this purpose. This part is working correctly (and well I might add!).

       

      The issue we have is that some of the objects in our session reference objects that are obtained via the Spring Autowire mechanism. Obviously these objects do not "work" when deserialized on a different server.

       

      I've tried creating a custom implementation of StreamingMarshaller to handle autowiring during unmarshalling but unfortunately the object that comes through that class is (apparently) a SingleRcpCommand object and so our application level objects are not readily available to this marshaller.

       

      Is there a better way to handle hooking into the deserialization process to handle autowiring/injecting depedencies? I also feel like this might be a common use case that maybe already has an existing implementation... Does anyone know if that's the case?

       

      Assuming there are not any good solutions for v4.2.1, I'm now turning to the v5.0 Externalizer mechanism. This looks promising but I'm curious if there are any "gotchas" to be aware of before I starting designing/implementing.

       

      My initial design idea follow this flow:

       

      1. In our AbstractSessionManager method that retrieves an HTTP session from the Infinispan cache, set the ApplicationContext in a ThreadLocal so that it can be obtained by the Externalizers.
      2. In the Externalizer implementations obtain the application context and autowire the dependencies.
      3. Back in the session mananger, remove the thread local application context once the session has been deserialized.

       

      Should that work?

       

      Thanks for the help!

       

      Regards,

      John


        • 1. Re: How to re-autowire/inject transient fields from Spring/IoC during deserialization?
          pmuir

          How about creating an interceptor do do this. To get the value, call InvocationContext#lookupEntry(key), where you get the key from the command being interceptor (DataCommand#getKey) and can then call CacheEntry#getValue() to get the actual object.

          1 of 1 people found this helpful
          • 2. Re: How to re-autowire/inject transient fields from Spring/IoC during deserialization?
            johncommon

            Pete,

             

            Thanks for the suggestion! I think using interceptors would work but I think I'd still be left navigating the object graph to find the places that need autowiring. Is that right? Does the interceptor work only at the top level object being stored or would the interceptor be called on each object in the graph that is being serialized? It sounds like the former which is the hole in my original thinking. I need to check for autowiring *each* object that is placed in the cache whether directly or via object references.

             

            I did implement the v5 Externalizer solution and it has worked great. It is dependent on a ThreadLocal but the design works well and the Externalizers are easy enough to implement.

             

            Thanks!

             

            Regards,

            John

            • 3. Re: How to re-autowire/inject transient fields from Spring/IoC during deserialization?
              galder.zamarreno

              The interceptor gets called once per each cache.put() or equivalent op, not whenever an object of the graph is going to be serialized.

               

              Nice to hear that the Externalizer extensions introduced in 5.0 are helping here. Is this code available somewhere?