Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have Spring's @Component on enum?

Tags:

java

enums

spring

I'm using Spring 3.0.x and following the enum singleton pattern for one of my implementatons.

public enum Person implements Nameable {
    INSTANCE;

    public String getName(){
        // return name somehow (Having a variable but omitted for brevity)
    }
}

Recently we started to collecting those types via Spring so I need to add @Component to my class.

@Component
public enum Person implements Nameable {
    INSTANCE;

    public String getName(){
        // return name somehow (Having a variable but omitted for brevity)
    }
}

and collecting method is

@Autowired
public void collectNameables(List<Nameable> all){
    // do something 
}

After doing this I observed failures and cause was Spring cannot intialize enum classes (which is understandable).

My question is -
Is there any other way usign which I can mark my enum classes as a bean ?
Or i need to change my implementation?

like image 940
Premraj Avatar asked Apr 27 '11 10:04

Premraj


People also ask

Can enum be Spring component?

You won't need to use the enum singleton pattern if you're using Spring to manage dependency injection. You can change your Person to a normal class. Spring will use the default scope of singleton, so all Spring-injected objects will get the same instance.

Can we use @component and @service together?

We can use @Component across the application to mark the beans as Spring's managed components. Spring will only pick up and register beans with @Component, and doesn't look for @Service and @Repository in general. @Service and @Repository are special cases of @Component.

At what level @component annotation is provided?

@Component is a class-level annotation, but @Bean is at the method level, so @Component is only an option when a class's source code is editable.


2 Answers

If you really need to use enum-based singleton (despite the fact that Spring beans are singletons by default), you need to use some other way to register that bean in the Spring context. For example, you can use XML configuration:

<util:constant static-field="...Person.INSTANCE"/>

or implement a FactoryBean:

@Component
public class PersonFactory implements FactoryBean<Person> {
    public Person getObject() throws Exception {
        return Person.INSTANCE;
    }

    public Class<?> getObjectType() {
        return Person.class;
    }

    public boolean isSingleton() {
        return true;
    }
}
like image 163
axtavt Avatar answered Sep 28 '22 14:09

axtavt


You won't need to use the enum singleton pattern if you're using Spring to manage dependency injection. You can change your Person to a normal class. Spring will use the default scope of singleton, so all Spring-injected objects will get the same instance.

like image 35
artbristol Avatar answered Sep 24 '22 14:09

artbristol