IoC and Convention Over Configuration/DRY - the real power of Java EE 5

I never really understood (I'm not the only person, I found also some other entries [Inversion of Control containers... still not getting it,Getting rid of IoC] about this), the real added value of the Inversion Of Control/Dependency Injection Pattern using getters and setters and an external XML. It is hard to develop, debug, maintain - but should be easy to extend and test.
I do not really make a difference between Java-Code and XML. In production you have to maintain both items in a (SVN) repository
and it is very unlikely that someone will change things in a dynamic way. And you have also to maintain two artifacts (source and XML)
in parallel with some redundant information which is not DRY (Don't Repeat Yourself).

Java EE 5 does not require XML-configuration and uses annotations instead. From the Separation Of Concerns perspective it is
not very clean, but pragmatic. To use an EJB B from an EJB A you have only to provide the @EJB annotation.
It looks like:


public class BeanA {

    @EJB   //reference name and type inferred from member
    private BeanB b;


    public void hello(){
        b.helloPlease();

    }

}

The overhead here is the annotation @EJB. The type and name are automatically inferred - so here is no need to specifiy this redundant information in (redundant)
external XML-files. But it is still possible, you are still able to override the default using XML.
The cool story here: the reference is injected directly into the private member. This violates a little bit the principle of private :-), but is also
very pragmatic, convenient and lean. Setters/getters are evil so are not needed any more... If you like you can of course go the old way and use setter/getter injection instead
the direct flavor (e.g. for debugging purposes).
So IoC with the notion of DRY and Convention Over Configuration are really powerful and very lean. If you like to see IoC in action just try Java EE 5 :-).
Actually it is only a syntactic sugar, behind the scenes, JNDI lookup etc. is still used.

I see the real benefit of IoC in combination with Convention Over Configuration, but I still do not see an advantage of using accessor based IoC with external (XML) configuration files.



Web Apps, SPA, PWA with vanilla Java Script (ES 6+), CSS 3 and WebStandards only. As simple as possible, but not simpler. See you at: (Progressive) Web apps, Single Page Apps and WebStandards airhacks workshops at MUC airport, Winter Edition

airhacks.fm the podcast:

Stay in touch: airhacks.news.

Comments:

IOC allows you to unit test easily with Mock object and also makes you program to interfaces. This means the implementation of a particular object can change without having to change all usages of e.g. UserManager can be replaced with a CachingUserManager or even a LDAPUsermanager.

This makes you code highly reusable and easy to test.

Posted by Owen Fellows on September 18, 2006 at 03:30 PM CEST #

Owen,

you are right. But: the same you can also achieve with a simple Factory, without an additional framework. Programming against interfaces is also not always suitable (it will double the amount of artifacts which increases the complexity). Nothing against the "classic" IoC, but in the practice I'm already delighted in case developers provide some tests for external, visible, interfaces :-). I never saw a project with a TestCase and mock for every single class.
Is it common in your projects?

Posted by Adam Bien on September 18, 2006 at 03:42 PM CEST #

Adam,

Usually I avoid the "I really don't understand IoC" debate; nevertheless I had to write a few lines this time;)

Of course setter injection is kind a awkward - if and only if - it's all you look at. A lot of spring guys recommend modeling your dependencies a little bit differently: Required dependencies use constructor injection, optional dependencies use setter injection. With autowiring turned on there isn't much in your XML file apart from class names that should be handled by your favorite IDE automatically. If you look at spring xml you will even notice another important feature: The ability to provide runtime configuration (e.g. username,password, etc.) to your components the same way you define your system configuration (FooBarService, YaddaDataSource). If you don't know what I am talking about do yourself a favor and look at Spring PropertyPlaceHolder (and equal) from the perspective of externalized runtime configuration;).

Regarding your love for EJB 3.0: In my opinion EJB 3.0 SLSB/SFSB/MDB provide a simpler programming model only. And a dangerous one, too. In the past months I have seen early stage EJB 3.0 applications where people use DI almost everywhere. Everything that would have been in a static helper class ends up being an SLSB. "Since it's so easy!" Hopefully it's just a bad impression on my side. But if I am correct we will see a lot more bad performing EJB applications than in early EJB 1.x or 2.x times. (I love JPA btw.;)

I can't follow your statements regarding interfaces and factories either. DI/IoC should focus on components only. Too bad spring used the misleading term “beans” for their configuration file. In my opinion an IoC container provides a simple non-visible component infrastructure and that’s pretty much it. Therefore you should not have a problem with interfaces at all, since a component should expose an interface first. Also I try to avoid factories these days. Personally I believe they introduce a central and due to their nature (static/singleton) dangerous dependency that requires - especially when tested within unit tests - additional configuration. With factories there is a good chance that I end up with a deep dependency tree that needs to be mocked up at some point in order to test it. As opposite to constructor injection: “You want to test me? Here is what I need. Give it to me.”

Last question: If you use DI for private fields – how do you test this component? Booting an EJB 3.0 container within a unit test? You must be kidding;)

Cheers,

Jens

Posted by Jens Schumann on September 18, 2006 at 06:53 PM CEST #

Jens,

thank you for your detailed comment.
0. I really did not understood the hype about IoC and DI. It is not a debate, only a statement. Hypes are suspicious.
1. IoC container is nothing else than a factored out generic factory :-). For "generic" we have to pay with extensive configuration.
2. EJB 3 is easy, but from my point of view it is not a drawback. Overuse is a general problem of every new technology.
3. I'm glad you mention the component level here. Using IoC for fine grained classes leads to overcomplication.
4. Factory has not to be a singleton. Static is an implementation problem.
5. JBoss provides a notion of micro-container which was built exaclty for booting during tests. I really prefer integration tests over unit + mocking AND integration tests. Booting is perhaps to hard - autodeploying is often good enough. Exactly what I do now!
6. I will discuss interfaces/classes factories in next entry - you comments are always welcome.
7. I do not love EJB 3.0. In only like the synergy between IoC and Convention Over Configuration. Spring-guys also seem to like it - see project pitchfork.
8...
9...:-)

We have to discuss these interesting topics somewhere else :-)

Posted by Adam Bien on September 18, 2006 at 07:13 PM CEST #

We should discuss these topics somewhere else. Too bad I have been tied up somewhere in nowhere lately;)

Reg. 1: Initially I thought the same way. But let me ask you this: How do you visualize your runtime system configuration defined by annotations? Of course, there will be tools some day. But can they distinguish between available and used at runtime? As of today I prefer a slick XML config for this. (I don’t follow the "Do everything with Spring" philosophy though). So XML doesn't need to be painful. It could also be part of the system documentation and thus follow DRY.

Reg. 2: I believe EJB 3.0 is a huge step forward. But the easy programming model hides it’s heavyweight nature. Too much, if you ask me. @Stateless doesn’t mean I have a simple class in my hands. But this is what I saw in early stage projects.

Reg. 5: I did expect this answer;). Of course it works, but seems to be another workaround for a design time error. I prefer new Object(), an inline implementation of an interface and lightweight tests – on component level, of course. It’s just too bad that JPA was able to do it and the rest of EJB 3.0 wasn’t.

Posted by Jens Schumann on September 18, 2006 at 07:55 PM CEST #

@Jens: 150% ACK. You're clear and right as always.

Posted by Stephan Schmidt on September 18, 2006 at 08:07 PM CEST #

Jens,

although my weblogger marked your comment as spam, the content is o.k. :-).

Reg 1: The visualization of dependencies should much easier than in the old J2EE 1.4 days. You know the interface, because of Convention Over Configuration the name is inferred. I think it is not a big deal to write an eclipse or netbeans plugin to do this. Is easier, than XML-parsing.

Reg 2: EJB 3.0 are a great revolution :-). But you are right: an EJB will always behave in a container differently, than outside. This is the reason why I prefer testing inside a container.

Reg 5: I agree with you: it is only a workaround, and I also do not like it :-).
I playing around with glassfish now. Autodeployment of a small project (10 JPA-Entities, 15 SLSB) takes about 5-10 seconds so it is acceptable. I had already some trouble with "overmocking". Developers built an own "heal" world and did not test the software in the production environment. The project almost failed... So continuus integration, if possible without mocking is very important.

It's funny. I only liked to mention with my entry, that Java EE 5 is easier (regarding the overhead, not concepts) and your comment pointed out, that the DI is too easy :-).

Posted by Adam Bien on September 18, 2006 at 09:53 PM CEST #

Adam,

I agree with you on some points. A lot of the IoC guys are just plain missing the point. More thoughts at <a href="http://blogs.concedere.net:8080/blog/discipline/software+engineering/?permalink=Encapsulation-IoC.html">Encapsulation > IoC</a>.

Posted by ocean on September 19, 2006 at 07:57 PM CEST #

Jens,

you can of course still use getters and setters and XML-Deployment Descriptors in Java EE 5 world if you like it :-)

Posted by Adam Bien on September 20, 2006 at 11:45 AM CEST #

Ocean,

I put some trackbacks to your entry. I agree with you.

Posted by Adam Bien on September 20, 2006 at 11:48 AM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
Online Workshops
realworldpatterns.com
...the last 150 posts
...the last 10 comments
License