Single spring bean with two different ids in same xml(application context) - spring

If we create a new another bean with different id in the same xml for the same class, will spring produce another singleton bean(in same ApplicationContext)?
As per my understanding there should be only one instance of the bean in single ApplicationContext.
Below example-
<bean id="bean1" class="com.myCompany.myPackage.MyClass" scope="singleton" />
<bean id="bean2" class="com.myCompany.myPackage.MyClass" scope="singleton" />

To keep it short: No, the singleton only says that you'll have: "one shared instance, which will be returned by all calls to getBean with the given id" (that's what the documentation states).
So, you can do any number of calls to application context and obtain "bean1" and you'll always get the same instance, but if you call by "bean2" id, you'll get another instance.
The "singleton" says that you'll have only one object. Now in a non-Spring application, you'll have it usually per JVM. But in spring application, let the framework manage this. So usually you'll want to define only one class like "MyClass" with a scope singleton.
When dependency management container (Spring in this case) manages singletons, it has a lot of advantages over the 'regular' singleton. Just to name a few:
Much easier to test
You always know when the object is created and when it becomes subject to garbage collector
No static code (the Spring driven singleton is just a regular bean with no statics)
But in general it's not directly related to your question.

I did have this same question just in a different context of Spring's singleton vs. Java's singleton and I found this answer provided by 'Dexter' in this link more subtle and easy to understand.
Also, this blog here provides a perfect example for the same which is backed by the official spring documentation for better-detailed understanding.
Hope these pointers help. Thanks.

Related

How to redefine Spring beans representation

I would like to add extra attribute to the internal representation of beans in Spring. Is it possible? What mechanism should be applied if any?
My goal is to define my own beans for my framework. I can do it from scratch or reuse Spring mechanisms.
You could have a look at the documentation Container Extension Points.
To achieve customization you can create a:
BeanPostProcessor bean which operates on a bean instance. For example this allows to create a custom bean registry, to proxify...
BeanFactoryPostProcessor which can operate on bean metadata. This allows for overriding or adding properties even to eager-initializing beans, modifying the class...
BeanDefinitionRegistryPostProcessor which can operate right after the registry initialization. This allows to create, remove or update beans definitions.
For example you can create a new BeanDefinitionRegistryPostProcessor which will register (or modify) beans using a custom implementation of BeanDefinition which will contain custom attribute based on for example your owns annotation.
Could you elaborate a bit what are you trying to achieve with your framework?
Merci beaucoup, Nicolas :)
I will study both your answer and the documentation you provided. I have already found the *Postprocessors you mentioned but I was not sure if this is the right place and what is the nature of their customizations (subclassing or something different) and what are the consequences. My problem is not as simple as I told (not just adding an attribute) - the extended Spring bean should be used also in cooperation to Spring+AspectJ (not SpringAOP), especially with declare-parents construct. I would like to be able to create proxies for the redefined beans as well. I will let you know what are the results of my investigation and may be I will ask some questions.
And the answer to all of you:
My framework is dedicated to defining graph modeling languages (meta-models) at run-time (being far extension of OMG standards) and I am looking for solutions of limits introduced by current object representation in JVM, which promotes behaviour over structure. This is one of several approaches, but the most prospective for me due to the relatively small effort.

getting bean id of target class in advice

I have a few classes that interact with databases (more than one). Some classes are reused so for example "obs.table1" is used to interact with table1 in database "obs" while "ref.table1" is used to interact with table1 in database "ref". These databases are at different URLs and each gets its own connection pool, etc... obs.table1 and ref.table1 are both instances of MyTable1Class, defined in beans file.
I have a pointcut that intercepts calls to methods annotated with #Transactional or with a custom annotation #MyTablesAnnotation and have it set so those calls will all get routed into a #Around advice.
This all works and the flow through the advice is correct.
What I am trying to add is reporting on what is going on in there. Currently I can tell where in there I am, but I can't tell if it was obs.table1 or ref.table1 object that got me there.
Is there a way to extract the bean id of the object on whose method the advice was invoked on?
ProceedingJoinPoint that is passed to the method the only thing I do with it is call a .proceed on it and the rest is just various checks and catches. I see that I can get either the target class or proxy class out of it, but... not sure how to go from there to knowing what the bean id was.
Is it possible?
Firstly it is not recommended to depend on bean id as it creates tight coupling with framework.
To quote from docs Note that it is not usually recommended that an object depend on its bean name, as this represents a potentially brittle dependence on external configuration, as well as a possibly unnecessary dependence on a Spring API.
Now to answer your question yes it is possible to fetch the name of bean via org.springframework.beans.factory.BeanNameAware.
The class for which you require the bean name should implement it and spring will auto-magically inject the name of the bean. However there is a gotcha which you should be aware and is mentioned in docs here

abount the singleton beans of spring

I am reading the 《Spring in Action》, and it says "singleton beans in Spring often don't maintain state because they're usually shared among multiple threads", but in my opinion, a bean in Spring is a POJO, so how can it not maintain state?
I am reading the 《Spring in Action》, and it says "singleton beans in
Spring often don't maintain state because they're usually shared among
multiple threads", but in my opinion, a bean in Spring is a POJO, so
how can it not maintain state?
Yes, it's better for a Spring/Singleton to not have a state (of course it can uses other Spring/Singletons [also them without a state]) so you can call its methods from different threads without worring about they could messed up its state (it doesn't have one :-)).
Let's think about a calculator that stores its intermediate results inside an internal stack, what can happen if two threads try to calculate something at the same time?
A Spring/Singleton is annotated (and if it's not it's just like it would be) and lives inside the spring context , it's not a POJO.
If you want to have a Spring/Bean with a state you have to use the scope "prototype", with this kind of scope every time you get a bean you will get a difference instance.
Sorry for the bad english
The book is implying that the state of a bean may not be trustworthy at a given point in time due to manipulation of its state by another thread. If multiple threads are accessing the same instance of a bean you cannot be sure of what state changes have occurred on the bean prior to using it. Since Spring uses Singletons by default there is only one instance of a bean. If multiple threads hit the bean at the same time there could be issues with the state of the bean.
So your correct that the beans will maintain state, however the state may be unreliable due to modifications from other threads.
In a typical web application, you have multiple threads (one per request) and all the requests are using the same beans. In a typical layered application, they will uses a Controller which uses then a Service which uses then a Repository. All of these beans should be singletons without any state. Otherwise you will have bugs due to concurrency (e.g. one thread modifies data in a singleton while another thread do the same).
I think that your misunderstanding comes from saying that bean in Spring are POJO. Most of Spring beans are stateless beans which I would not describe as POJO.
A Spring bean is considered a POJO in the sense that it does not need to adhere to special requirements (implement certain interfaces, extend particular class, be specific in some way, etc.) to be used with Spring.
Depending on the requirements a Spring bean might need to maintain, and operate on, its state.
It also depends on the requirements to consider if the Spring bean should be a singleton or not.
If a singleton Spring bean is maintaining its own state, proper safeguards must be taken to ensure correct concurrent access/modification.
Confusion comes from a general pattern used in enterprise applications where Spring beans are used to implement bulk of the system logic, and support operations.
In these scenarios, generally its a good practice to not have any state in the Spring bean itself, and just be an extension of the Value Object/Data Transfer Object that contain actual state.
Since these Spring beans are not going to maintain their own state, they are almost always created as singletons.
SomeClass, SomeOtherClass and Situation are all POJO in below code.
SomeClass and SomeOtherClass are Spring beans but Situation is not, which is a DTO.
class SomeClass {
private int x; // not restricted
public void handleSituation(Situation s) {
// may or may not use/modify SomeClass state represented by 'x'
// one approach is to provide all required information through parameters
}
}
class SomeOtherClass {
#Autowired
private SomeClass sc;
public void process() {
// gets called from another object
Situation z = new Situation();
sc.handleSituation(z);
// other processing
}
}
<!-- default scope = singleton -->
<bean id="someClassBean" class="SomeClass"/>
<bean id="someOtherClassBean" class="SomeOtherClass">
<property name="someClass" ref="someClassBean"/>
</bean>
This is a slight variation from pure OOP in which above would be coded similar to following.
class SomeOtherClass {
public void process() {
// gets called from another object
Situation z = new Situation();
z.handle();
// other processing
}
}

Creating non-bean instances with Spring

I'm sure this has been asked a hundred times before but I can't seem to find the question so feel free to refer me to other stackoverflow answers.
What do most Spring users do for objects that are non-singleton beans that require injection? For example, I have classes like Customer where I want to instantiate a new one each time. Lets say it is an entity and I want to inject listeners to iterate through in #PreRemove or somewhere else. The usual solution is to use #Configurable but that almost seems a workaround and I was wonder if there was a more canonical way to handle these.
The only thing I can think of is to create a factory newCustomer instance method in my CustomerRepository class which IS a managed bean. Then instead of injecting listeners into Customer (the most natural place) I inject them into the CustomerRepository and specify them as an explicit constructor argument to Customer ala new Customer( injectedListeners ).
Do people tend to just use Configurable or is there a better way to inject non-singleton instances? Or do most users create a factory method as above? The entity example is just an example, I have other objects that are non-singleton, are typically new'd but require injection.
Would this be handled differently in something like Guice? How would you do it just using JSR-330 features?
You can make beans non-singletons if you like. Depends on whether you are ok with the XML:
<bean id="beanA" class="misc.BeanClass" scope="prototype">
<property ... />
</bean>
Which will give you a new instance every time. Each instance will be initialized with injected values.
You can use this annotation too:
#Scope("prototype")

Constructors in Bean

I have one small issue with creating a new bean. Basically as per request, I get some parameters, which needs to be passed to a bean. Below I am instantiating ControllerService for each request. Rather I would like it to be a bean with scope=protype. So that I get a fresh object for every request.
But then how do i set the 2 properties (kpiName, kpiInput) that I am sending via constructors in the bean??
#Autowired
#Qualifier("serviceManager")
Cleanser serviceManager;
#RequestMapping(method = RequestMethod.POST)
public #ResponseBody
String getKPIResult(#RequestParam("kpiName") String kpiName,
#RequestParam("kpiInput") String kpiInput) {
return serviceManager.checkAndExecute(new ControllerService(kpiName, kpiInput));
}
In situations like this where you're going against the grain of Spring, I'd suggest that perhaps you're doing something in a way that's not considered best practice. Without more context it's hard to see though.
Spring Social uses a request scope bean to embody a repository for a specific user. I've now idea why as it's a horribly inefficient way of doing things, and much less understandable IMHO.
<bean id="connectionRepository" factory-method="createConnectionRepository"
factory-bean="usersConnectionRepository" scope="request">
<constructor-arg
value="#{T(org.springframework.security.core.context.SecurityContextHolder).getContext().getAuthentication().getPrincipal()}" />
<aop:scoped-proxy proxy-target-class="false" />
</bean>
You can see here the use of factory-bean and factory-method to declare a class/method to call when wanting an instance of your class. The constructor argument is passed using SpEL. I'm not quite sure how you'd achieve this with Spring MVC responding to web requests, but I'm fairly sure you could use Spring Integration to pass a message and use SpEL to grab headers/payload form that message to pass to the constructor.
Again though, I'd really question your design pattern here - a more usual SOA idiom is to create services on startup, and have them as stateless as possible from there-on in, rather than create an instance with specific state for each request. Best of luck!
Don't. The Controller as it's intended in Spring MVC is largely derived from the old Java servlet, which should be stateless by specification.
In fact, Controller-objects are hard-cached inside the handler mapping framework and not fetched from the bean context on each request. Setting scope to "prototype" would, effectively, do nothing as the handler (controller) is really only gotten once.

Resources