views:

51

answers:

2

Simplified Architecture of Web Projects

  • WAR

    • spring dependency injection (most use XML)
  • JAR

    • DAO
    • Domain

The Problem: With Spring 3 and 2.5+ annotations building Repositories and services has become much easier to wire together. However, because often a @Service conceptually belongs in the JAR far more than the WAR, and certainly auto-wired Repositories, and transactional classes, do. How do people work where it's expected to not have "spring dependencies" in the actual JAR classes, which I've found in multiple companies is a goal.

Obviously I know you cannot remove ALL spring dependencies if you want to use Annotations and Transactions, since they are actually spring classes, but is there some best practice people use that limit the liability if there are changes to spring, or there are projects that use OLDER spring versions in their WAR than what is included in the JAR?

I'm assuming this must be a common problem, but if not, please ask and I will elaborate

+3  A: 

Annotation based dependency injection is essentially a (very convenient) violation of Separation of Concerns. The dependency you describe is the result of this. If you would like to avoid it you should do your wiring in a separate package (i.e. not use annotations for dependency injection).

It is possible however to wire based on your own custom annotations. Depending on how far you are willing to go this can improve things to leave only a single spring dependency (your extending annotation) or remove the dependencies altogether. This still violates SoC, but with much less dependency on Spring.

Usually I find that either living with the downsides of annotations, or completely living without them (using Java Config or plain old XML) are the most maintainable options. Custom annotations are another maintenance burden.

iwein
any experience with the @Transactional annotation?
walnutmon
@jboyd: lots in fact, i love it. It is possible to do it from xml, but that would be at the bottom of my list. You can also use @TransactionAttribute (the JPA equivalent).
iwein
@iwein - if I use @TransactionAttribute to remove my dependency from Spring, would I need to do everything through JPA? Or can I just use the JPA transaction annotations, with a spring implementation?
walnutmon
@jboyd you could use @TransactionAttribute with a spring implementation of your @Repository, to avoid a Spring dependency in your service layer while it still exists in your data access layer, but this is a little far fetched I'd say. This is not limited by Spring as far as I know.
iwein
@iwein - well @TransactionAttribute is a JPA dependency, so if you had that, with a spring implementation, the spring dependency would be at runtime, not at compile time, so you'd have removed all spring dependencies from your data access layer
walnutmon
@walnutmon @TransactionAttribute should usually be on the service, not the repository. The spring implementation is about using e.g. JdbcTemplate in the repositories, right?
iwein
A: 

I've been married with the Spring Framework for a while and we use it extensively at my current work. One of the advantages of using Spring is that it was designed to be as less intrusive as possible, that is, you seldom have to implement some Spring specific interface, etc.

Unfortunately the best approach you can take, as far as I'm concerned, to minimize the dependency on spring classes due to the annotations use, is the use of XML configuration files, which also have its downside.

At the end of the day, as I see it, is that there is always a price to pay.

StudiousJoseph