s2-logoUsing Spring, it is easy to inject any instance with its dependencies, as long as the instance is managed by the Spring container. This typically means that the to-be injected beans are configured in the XML configuration. However, sometimes, it is impossible or ugly design to have objects managed by the Spring container. For example, when using a Rich Domain Model , your application will instantiate domain objects that contain domain logic, and thus need their dependencies to be injected.

A commonly seen strategy to inject these dependencies is to call a static method from the constructor. This static method will inject the newly instantiated instance with its dependencies using a reference to Spring’s application context. Although this method seems effective, it is purely limited to dependency injection. Spring offers a lot more, such as transaction support and security.

Spring’s load time weaving capabilty offers a more complete way to inject your unmanaged instances, making them no different than any spring managed instance.


Configuring Load Time Weaving
Load Time Weaving (LTW) is the process of modification of byte code the moment a class is loaded and is often seen in AOP. When a class is loaded from disk and placed into memory be a ClassLoader, the byte code is evaluated and, if necessary, modified before it is made available to the application.

Enabling Spring’s load time weaving can be very simple. When you’re unlucky, it can get a little harder, but still easy. All you need to do is add the following to your application context:

<context:spring-configured/>

That can’t be all, can it? Well, that depends of the classloader loads your application. Spring will autodetect the classloader, and depending on the implementation, tell it to modify classes before loading them into memory. Unfortunately, not all class loaders are compatible with this approach.

According to Spring’s documentation, this method is compatible with the class loaders used by WebLogic 10, Oracle OC4J and Glassfish. If your class loader is not in this list, don’t worry, there is still hope. Tomcat users can configure Tomcat to use the TomcatInstrumentableClassLoader by putting the spring-tomcat-weaver.jar in the common/lib folder and adding the following snippet to META-INF/context.xml in the WAR root:

<Context>
    <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
            useSystemClassLoaderAsParent="false"/>
</Context>

This tells Tomcat to use another ClassLoader, which Spring can use to perform the weaving. See Tomcat Documentation for more about this type of configuration.

Another way to keep the ability to inject dependencies to unmanaged classes, is by instrumentation. Ben has written an article about how this works. Spring offers a JAR file that does the proper JVM instrumentation to allow load time weaving using any class loader. When starting your application, use the -javaagent:/path/to/spring-agent.jar parameter to load the LTW agent.

Dependency Injection configuration
Now that we have Spring watching our newly instantiated instances, we have to tell it how to inject them. That is, with which objects.

Independent of the option you choose, you have to annotate the class with @Configurable. This tells Spring that this unmanaged class is configurable using the Spring Application Context.

If you want to use auto wiring, all you need is to put the @Autowired annotation on either the setter or the field. Don’t forget to add the annotation support to your context, for example with the <context:annotation-config/> element, or the AutowiredAnnotationBeanPostProcessor.

You can also configure your unmanged class using XML configuration. Here is an example:

The java file:

@Configurable
public class DomainClass {

  private transient SomeDependency someDependency;

  // some logic

  public void setSomeDependency(SomeDependency someDependency) {
    // default setter logic
  }
}

The XML configuration:

<bean class="my.DomainClass" scope="prototype" abstract="true">
    <property name="someDependency" ref="someDependency"/>
</bean>

Notice that the property is made transient. I’ve done this, because this property shouldn’t be persisted or serialized. When the object is deserialized, Spring will automatically wire the object again. The same thing goes for persistence.

Spring will be able to relate this bean configuration to the newly instantiated class (through the id, which is defaulted to the class name) and wire your newly created instance according to the XML configuration. If you prefer to be more explicit, you can pass the id of the prototype bean in the value property of the @Configurable annotation. This will force Spring to look for the definition with the given bean id.

Dependencies
Almost forgot, if you want to use load time weaving, you need spring-aspects, aspectjrt and the usual spring jars on your classpath.

AOP using AspectJ
The good news is that you’re very close to being able to use AspectJ now. All you need to do now is configure the appropriate aspects and classes to weave using the META-INF/aop.xml files. It is beyond the scope of this article, but I couldn’t resist pointing you in the right direction.

Injecting Domain objects with Spring
Tagged on: