Skip to main content

DDD in Spring made easy with AspectJ

UPDATE: Over the years I learnt that the solution provided below is not really an example of domain-driven design. It's more like an active record implementation on top of Spring. But the technical part of the article is still relevant, so I keep it intact.

Before I start the main topic, I would like you to think for a while about the best JEE application design you can imagine. No matter you use Spring or EJB3, as they are very similar, probably you would suggest similar approach. Starting from the back you have:

  • domain objects, which are simple POJOs mapped directly to database relations. POJOs are great because JavaBean-style properties are well understood be many frameworks.
  • data access layer – typically stateless services, which wrap up database access code (JDBC, Hibernate, JPA, iBatis or whatever you want) hiding its complexity and providing some level of (leaky) abstraction. DAOs are great because they hide nasty and awkward JDBC logic (that is why some question the need for DAOs when using JPA, but this is out of scope of this post), serving as a, more-or-less, translator between database and objects.
  • business services layer – another set of stateless services, which operate on domain objects. Typical design introduces a graph of objects that take or return domain objects and perform some logic on them, again, typically accessing database via data access layer. Service layer is great because it focuses on business logic, delegating technical details to DAO layer.
  • user interface – nowadays, typically via web browser. User interface is great because... just the fact it is.
Beautiful, isn’t it? Now open your eyes, it is time for a cold shower.

Both services and DAOs are stateless, because Spring and EJB3 favors such classes - so we learnt to live with it. On the other hand, POJOs are "logicless" – they only contain data, maintain their state without operating on it and introducing no logic. If we think about introducing "reservation" domain object to our application, we immediately think of Reservation POJOs mapped to RESERVATIONS database table, ReservationDao, ReservationService, ReservationController, etc.

Still don’t see the problem, Java, thus OOP programmer? How would you describe "object"? It is some virtual being having internal (encapsulation) state and some public operations, which have explicit access to the state. Most fundamental concept of object-based programming is to take data and procedures operating on that data together and close them tightly. Now take a look at your best design ever, do you really need objects? This is the dark secret of Spring, EJB3, Hibernate and other well established frameworks. The secret, which all of us subconsciously try to forget: we are not OOP programmers anymore!

POJOs are not objects, they are simply data structures, collections of data. Getters and setters are not true methods, actually, when was the last time you wrote them by hand? In fact, the need to autogenerate them (and refactor, add and remove when attributes change) sometimes happen to be very frustrating. Wouldn’t it be simpler just to use structures with public fields by default?

On the other hand, look at all those great stateless services. They do not have any state. Although they operate on domain objects, they are not part of them or not even aggregate them (low cohesion). All the data is passed explicitly through the method parameters. They aren’t objects as well – they are simply collection of procedures arbitrary gathered together on a common namespace, corresponding to class name. In contracts, methods in OOP are also procedures behind the scenes, but having implicit access to this reference, which points to the object instance. Whenever we call ReservationService or ReservationDao providing Reservation POJO reference explicitly as one of the arguments, we actually reinvent OOP and code it manually.

Let’s face it, we are not OOP programmers, as everything we need are structures and procedures, invented fifty years ago... How many Java programmers are using inheritance and polymorphism in a day-to-day basis? When was the last time you wrote object having private state without getters/setters with only few method having access to it? When was the last time you created object with non-default constructor?

Luckily, what Spring have taken, it brings back with even more power. The power is called AspcetJ.

In my last post I created Reservation entity having three business methods: accept(), charge() and cancel(). It looks really good to have business methods concerning domain object placed directly in that object. Instead of calling reservationService.accept(reservation), we simply run reservation.accept(), which is much more intuitive and less noisy. Even better, what about writing:

Reservation res = new Reservation()

instead of calling DAO or EntityManager directly? I don’t know much about domain-driven design, but I found this fundamental refactoring to be the first gate you must walk through to enter the DDD world (and go back to OOP as well).

So, if having business methods directly on domain objects is so great, why not everybody’s doing it? The answer is very straightforward and down-to-earth – because they don’t know how! Reservations’ accept() method will eventually need to delegate some logic to external services, like accounting or sending e-mails. Naturally, this logic is not part of Reservation domain object and should be implemented elsewhere (high cohesion). But most Spring programmers don’t know how or are scared of injecting other services to domain objects. When all services are managed by Spring, everything is simple. But when Hibernate creates domain objects itself or the object is created using new operator, Spring has no knowledge of this instance and cannot handle dependency injection. So how would Reservation POJO obtain Spring beans or EntityManager encapsulating necessary logic?


First, add @Configurable annotation to your domain object:

public class Reservation implements Serializable {

This tells Spring that Reservation POJO should be managed by Spring. But, as mentioned above, Spring has no knowledge of Reservation instances being created, so it has no occasion to autowire and inject dependencies. This is where AspectJ comes in. All you need to do is to add:


To your Spring XML descriptor. This extremely short XML snippet tells Spring that it should use AspectJ load-time weaving (LTW). Now, when you run you application:

java.lang.IllegalStateException: ClassLoader [org.apache.catalina.loader.WebappClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:spring-agent.jar
at org.springframework.context.weaving.DefaultContextLoadTimeWeaver.setBeanClassLoader(
... 59 more

It will fail... Java is not magic, so before we proceed, few words of explanation – don’t be impatient. Adding XML snippet above does not solve anything. It simply tells Spring that we are using AspectJ LTW. But when application starts up, it does not find AspectJ and tells us about it decently. What happens if we add -javaagent:spring-agent.jar to our JVM command line parameters as suggested? This Java agent is simply a plugin to JVM that overrides loading of every class. When Reservation class is loaded for the first time, agent discovers @Configurable annotation and applies some special AspectJ aspect to this class.

To be more precise: bytecode of Reservation class is being modified, overriding all constructors and deserialization routines. Thanks to this modification, whenever new Reservation class is being instantiated, apart from normal initialization, those additional routines added by the Spring-provided aspect perform dependency injection. So since now enhanced Reservation class is Spring-aware. It does not matter whether reservation has been created by Hibernate, Struts2 or using new operator. Hidden aspect code always takes care of calling Spring ApplicationContext and ask it to inject all dependencies to domain object. Let us take it for a test drive:

public class Reservation implements Serializable {

private transient EntityManager em;

public void persist() {

This is not a mistake – I injected EntityManger from JPA specification directly to domain object. I also put @Transactional annotation over persist() method. This is not possible in ordinary Spring, but since we used @Configurable annotation and AspectJ LTW, code below is completely valid and works as expected, issuing SQL and committing transaction against the database:

Reservation res = new Reservation()

Of course, you can also inject regular dependencies (other Spring beans) to your domain objects. You have choice of using autowiring (@Autowire or even better @Resource annotations) or setting properties manually. The latter approach gives you more control, but forces you to add setter for Spring bean in domain object and define another bean corresponding to domain object:

<bean class=" com.blogspot.nurkiewicz.reservations.Reservation ">
<!-- ... -->

Please note that I haven’t provided name/id for this bean. If I would, the same name should be passed to @Configurable annotation.

Everything works like a charms, but how to use this amazing feature in your real life work? First of all, you must setup your unit tests to use Java agent. In IntelliJ IDEA I simply added:


to VM parameters text field in JUnit run configuration. If you add this to default ("Edit defaults" button), this parameter will be applied to every new unit test you run. But configuring IDE is not as much important as configuring your build tool (hopefully maven). First of all you must ensure that Spring Java agent is downloaded and available. Thanks to maven dependency resolution, this can be easily achieved by adding dependency:


The JAR is not actually needed by test code, but by adding this dependency we guarantee that it is downloaded before tests run. Then, simple tweak in surefire plugin configuration:


Really simple – location of spring-agent.jar can be safely constructed using maven repository path. Also forkMode must be set in order to reload classes (and cause LTW to happen) each test is executed. I think configuring your app server and/or startup scripts does not need any further explanation.

That is all about Spring and AspectJ integration via load-time weaving. Few simple configuration steps and a whole new world of domain-driven design welcomes. Our domain model is no longer weak, entities are "smart" and business code is more intuitive. And last but not least – your code would be back object-oriented, not procedural.

Of course, you might not like load-time weaving, as it interferes with JVM class loading. There is another approach, called compile-time weaving, which weaves aspects on compile time rather than class loading time. Both methods have pros and cons, I will try to compare both of them in the future.


  1. Great article, as usual, gratz :)

    It's nice that DDD is becoming more and more popular. Maybe, one day, we'll be able to say that our projects are realy object-oriented.
    I can't wait for your next DDD-related article!

    My few words about @Configurable and LTW, maybe as the introduction to your next article about LTW vs. CTW...

    I use @Configurable wherever Spring doesn't control my objects lifecycle and I need it's beans in this object (common examples are Quartz Jobs, JBPM objects, JSF custom validators). One day, a strange guy told me, that @Configurable is evil - it kills your application performance. I'm really curious to know is it true and how to implement that scenario (i.e. persist() in domain object) in other way. Are there any other solutions? Custom hibernate interceptors? Doesn't convince me...

    CTW (compile-time-weaving), as alternative to LTW is a better approach for me.

    I just add following [1] piece of code to my pom.xml and I can forget about IDE, surefire and also production server tuning (by adding extra parameters to JVM).

    There only might be one problem in your favourite IDE. When it will recompile your class using it's own builder/compiler (not maven), your aspects are gone. You have to run at least 'mvn compile' again and refresh compiled classes in IDE.

    Fortunately, in Eclipse Galileo+m2eclipse plugin it works pretty well. In IntelliJ it works even better, isn't it? ;)


  2. Thank you for your comment. To be honest I don’t know much about DDD, but I think I am quite good at OOP :-). As for @Configurable and way of weaving aspects, my next article will most likely explain how to use CTW instead of LTW in the same example project. This would be a very good foundation for performance comparison. Because the biggest truth of optimization is: don’t talk about performance, measure it!
    I planned to use aspectj-maven-plugin to enable CTW, but you provided piece of ANT code via antrun plugin. Personally I found using antrun awkward and against maven philosophy, so while playing with compile-time weaving I will try to use maven plugin mentioned above. I assume you tried it already, why you suggesting ANT task? And, yes, IntelliJ IDEA has dedicated plugin, but I have not tried it as well.
    You mention about Quartz jobs – if you use Spring support for Quartz, executed job can run any no-arg method of any Spring bean, so no need for @Configurable. But in many other scenarios it is irreplaceable.

  3. Very nice text man! Especially the first part is very enlightening. Martin Fowler calls this "procedural" way "Anemic Domain Model" (

    But I think doing OOP does not mean ALWAYS try to do object.operation(). Many times this is the way to go, but sometimes this can make the object too coupled with the context it is in. Or it gives him additional responsibility that should be given to another object. For example, I think


    is actually not as good as


    At least in this special case. Think about separation of concerns.. In the first case the Reservation has the additional concern of persisting itself. In the second case another object has this concern, and this is his primary job.

    Adding persist() inside Reservation, gives you a nicer syntax, but it also makes things less pure. The persist() method inside Reservation suggests that Reservation has another responsibility, namely to persist itself, and this is far away from the business domain and the business logic. If you add methods to a domain object, they should be only business methods IMHO.

  4. great post. i wanna share also a spoon-feed tutorial on Spring MVC

    hope it will help people!

  5. I'm agree with rfilipov.
    In this special case resonsibilities of repositories are merged into entities.
    However it is a good post: the same technic can be used to inject services in entities that maybe can be more useful than repositories

  6. What about leaving the @Transactional annotation on the service and for dependecies injection using something like:
    AutowireCapableBeanFactory factory = appCtx.getAutowireCapableBeanFactory();
    you will avoid the black magic of AspectJ LTW and get all what you need at the cost of writing a bit more code, isn't it?

  7. Excellent article, although it's bit old now, but all questions and answers are good food for brain. Spring state machine could be interesting to look at as well.


Post a Comment