Adam Bien's Weblog

Monday Feb 07, 2011

Simplest Possible POJO Injection Example With Java EE 6

You can inject objects by annotating a field with javax.inject.Inject:


@Stateless
public class Cart {

    @Inject
    OrderSystem ordering;
    
    @Inject
    CustomerNotification notifier;

    public void checkout(){
        ordering.placeOrder();
        notifier.sendNotification();
    }
}


The existence of a no-arg constructor is sufficient:

public class OrderSystem {
   public void placeOrder(){
    }
}

You only need the beans.xml file in the [WAR]/WEB-INF folder with the content: <beans/>

[It is an excerpt from the project EJBAndCDI - it was pushed into http://kenai.com/projects/javaee-patterns.
The size of the WAR is 16kB (with JSF) and the initial deployment took 800ms (...somehow slow today :-)).]


NEW workshop: Microservices with Java EE 7 and Java 8, January 26th, 2015, Airport Munich

A book about rethinking Java EE Patterns

Comments:

hmmm... but OrderSystem must be a ManagedObject or a NamedObject.

Posted by Robert on February 07, 2011 at 03:26 PM CET #

@Robert,

it just works - try it - and write please another comment :-)

enjoy hacking!

adam

Posted by adam-bien.com on February 07, 2011 at 03:37 PM CET #

That's so easy. But what exactly is injected? Is it always a new instance of OrderSystem or is there some pooling used or it depends on the implementation? What's the difference to (new OrderSystem()).placeOrdrer()? Thanks!

Posted by Radek on February 07, 2011 at 03:57 PM CET #

The difference to (new OrderSystem()).placeOrdrer() is the testability, because you can easily mock the OrderSystem in your tests, which is hard if you create the object yourself.

Posted by Patrick Cornelissen on February 07, 2011 at 04:31 PM CET #

I'm not so happy to see this (imo bad) pattern propagated.

Of course it works, becaue if a class is not annotated with a special CDI scope, then it will automatically treated as being @Dependent. This means that the bean shares the lifecycle of the instance it gets injected into. = a new instance for every injection point

I personally don't like that because it tends to create more problems than it solves. E.g. if you by error import javax.faces.bean.SessionScoped instead of javax.enterprise.context.SessionScoped then you will end up with a dependent scoped bean WITHOUT getting warned!

Because of that, Apache OpenWebBeans will soon contain a (non spec-conform) mode which don't automagically pickup non-scoped beans as @Dependent. As a side effect this also boosts startup performance and decreases the mem footprint big times!

Posted by struberg on February 07, 2011 at 04:32 PM CET #

@Struberg,

some good points. However:
"Of course it works, becaue if a class is not annotated with a special CDI scope, then it will automatically treated as being @Dependent. This means that the bean shares the lifecycle of the instance it gets injected into. = a new instance for every injection point"

In this case it would mean, you would get an extra CDI Bean for every Stateless Session Bean instance. Under heavy load it could be > 30 instances. You made me curious - I will perform some load tests and measure the difference.

Mixing JSF and CDI scopes is a bigger problem - but it should be easy to identify during testing.

In my projects I would answer to such remark: "Premature Optimization is the root of all evil" :-) I would in fact go with plain @Inject and see what happens during the next daily/weekly stress test.

Thanks for your valuable comment. We should meet us at some conference and have a chat about Java EE 6 / CDI and the lightweight stuff :-)

thanks again!,

adam

Posted by adam-bien.com on February 07, 2011 at 05:11 PM CET #

I'll hold talks at the con-fess and jax.de this year. Think there will be a few beers waiting for us ;)

> Mixing JSF and CDI scopes is a bigger problem - but it should be easy to identify during testing.

Sadly this is not really easy easy to detect, because it's technically not a 'bug'.
One thing you can do is to use an Apache MyFaces CODI [1] extension which maps JSF scopes to their CDI counterparts.

LieGrue,
strub

[1] myfaces.apache.org/extensions/cdi

Posted by struberg on February 07, 2011 at 10:49 PM CET #

@Struberg,

or use WELD / Seam extensions for that :-),

see you at JAX!,

adam

Posted by adam-bien.com on February 08, 2011 at 12:23 AM CET #

Thanks! Was working with my own stuff, and I had everything except the beans.xml file. Couldn't figure out what was wrong until I found this post!

Posted by Dan on June 23, 2011 at 11:48 PM CEST #

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