views:

548

answers:

1

I came into IOC via Google Guice.

And now I've been forced to use Spring 2.5.6 at work & I am lost because Spring is quite complicated. Here are some questions after reading bits of the spring docs:

  • What is the difference between @Service, @Controller and @Component ? If I just want to auto wire my objects like Guice, do I need to be bothered by all these stereotypes ?
  • I'm planning to go the component-scan route with only constructor injection (Setter injection is mostly advocated by the Church of Scientology) and no freaking XML shit. So is this code extract all I need ?

    @Component
    public class Foo
    {
        @Autowired(required=true)
        public Foo( Bar bar, @Qualifier("yay") Boo yay, 
                    @Qualifier("hoo") Boo hoo )
        {
            _bar = bar; _boo = boo;
        }
    
    
    
    Bar _bar;
    Boo _boo;
    
    ....snipped... } @Component @Qualifier("yay") @Scope(BeanDefinition.SCOPE_PROTOTYPE) public BooYay implements Boo { } @Component @Qualifier("hoo") @Scope(BeanDefinition.SCOPE_PROTOTYPE) public BooHoo implements Boo { }
    • In the above example, did I correctly qualify the 2 different implementations of Boo ?
    • Is there any feature similar to Google Guice's Providers ?
    • How do I mimic the @Singleton behaviour (in Guice) in Spring ?

Thanks

+4  A: 

Looking at your code, it seems all fine and your components will get autowired. You must give your package name in XML config file, so Spring can scan that for annotations.

Spring-managed components in general, the default and most common scope for autodetected components is singleton.

Actually, @Component is a generalisation of @Service and @Controller. See the docs.

Spring 2.5 introduces further stereotype annotations: @Component, @Service and @Controller. @Component serves as a generic stereotype for any Spring-managed component; whereas, @Repository, @Service, and @Controller serve as specializations of @Component for more specific use cases (e.g., in the persistence, service, and presentation layers, respectively). What this means is that you can annotate your component classes with @Component, but by annotating them with @Repository, @Service, or @Controller instead, your classes are more properly suited for processing by tools or associating with aspects. For example, these stereotype annotations make ideal targets for pointcuts. Of course, it is also possible that @Repository, @Service, and @Controller may carry additional semantics in future releases of the Spring Framework. Thus, if you are making a decision between using @Component or @Service for your service layer, @Service is clearly the better choice. Similarly, as stated above, @Repository is already supported as a marker for automatic exception translation in your persistence layer.

Make sure that your default-autowire or autowire value for those beans is byType. And then you should modify your Boo components like below,

@Component("yay")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public BooYay implements Boo
{...}


@Component("hoo")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public BooHoo implements Boo
{...}

You might like to do it with autowire = "byName", in that case you will not need @Qualifiers, but have to provide the matching setters. I hope you will managed to knock the thing off now.

Adeel Ansari
Jacques René Mesrine
whats your `default-autowire` value?
Adeel Ansari
I'm currently working in a Jersey-Spring environment. It seems like I need to use a Jersey specific annotation to get autowire to work. This is too clunky for me. So I'm abandoning Spring and going back to Guice (which currently works just fine). My first forays into Spring just left a bad taste in my mouth.
Jacques René Mesrine