Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring behavior when mixing component scanning and XML bean definition for the same class?

Tags:

spring

I have a question regarding component scanning and the use of an additional bean-definition in the XML configuration for the same service class in Spring Version 3.0.5.RELEASE.

I created a class "MyService" annotated with

@Service( "myService" )

and there is a bean definition for the same class that looks like this:

<bean id="myService" class="....MyService" />

I put a

System.out.println( "MyService has been instantiated" );

message into the constructor of the MyService class. That message will be displayed at the console only once, when my application starts. Spring seems smart enough to detect, that there can be only one instance of that class with the id "myService".

But even when I change the annotation to

@Service( "myService2" )

and leave the xml bean definition id to "myService", the class will only be instantiated once.

My two questions are:

  1. Although that is the behavior that I currently want, is it possible to mix up XML bean definition and component scanning for one class, to have it instantiated twice with different Bean IDs?

  2. Does anyone know, what the mechanism is "behind the scenes" in Spring? How does Spring decide when to instantiate a class only once? (Maybe it is just not allowed to mix component scanning and XML bean definition for the same class?)

Thanks a lot for your help!

like image 299
It's Leto Avatar asked Sep 09 '11 08:09

It's Leto


2 Answers

Your question 2. can be answered easily. Spring instantiates beans depending on their scope. The default scope is "singleton", no matter if you use xml or annotation-based configuration. If you declare a bean as scope=prototype, it will get instantiated every time the container is asked for the bean.

As annotation:

@Scope(StandardScopes.PROTOTYPE)

In xml:

<bean .... scope="prototype">

If you need exactly two instances of a bean, the best would be to declare two of them with dfiferent names in XML I would think.

Concerning your question 1, I don't know if it is possible to declare two instances of a class, one using annotation and one using XML. Are you sure that classpath scanning really works in your example? Leave out the XML bean declaration and try again, do you have an instance of the bean then? If not, you should first fix the classpath scanning as it seems not to work.

Anyway, the most important question: Why would you want to do that? Mixing both types of configuration will create somewhat unmaintainable code. Don't mix the configuraton types, go for only one, or tell us why the heck you would need that.

like image 192
Moritz Both Avatar answered Oct 04 '22 08:10

Moritz Both


You can use component scan and at the same time define the bean in xml. However this depends on bean scope as well.

Read this post for more information.

If component scanning is enabled, spring will try to create a bean even though a bean of that class has already been defined in the spring config xml. However if the bean defined in the spring config file and the auto-discovered bean have the same name, spring will not to create a new bean while it does component scanning. If a bean does not have a no-args constructor, at-least one of the constructors must be auto-wired. If no constructor is auto-wired, spring will try to create an object using default no-args constructor.

like image 28
Fahim Farook Avatar answered Oct 04 '22 06:10

Fahim Farook