I have a singleton Spring bean (and it has to stay a singleton) which needs a fresh instance of another bean (Lets call it X) every time a certain method executes.
So far I looked at the following approaches:
just create X using new. This worked for a while but now we need spring AOP features for X, so this doesn't work anymore, since the resulting instances are not Spring managed.
I considered a FactoryBean as a dependency, but I would only get a single X instance from the FactoryBean, which doesn't meet my first instance.
the current plan is to manually lookup X in the Spring context, and declare it there with a prototype dependency. This should work, but I think it is really ugly.
=> How can I inject a factory in my bean so that I can call its factory method any time I see fit and getting a spring managed instance out of it.
For using Spring AOP in Spring beans, we need to do the following: Declare AOP namespace like xmlns:aop=“https://www.springframework.org/schema/aop” Add aop:aspectj-autoproxy element to enable Spring AspectJ support with auto proxy at runtime. Configure Aspect classes as other Spring beans.
In Spring AOP, aspects are implemented using regular classes (the schema-based approach) or regular classes annotated with the @Aspect annotation (the @AspectJ style). Join point: a point during the execution of a program, such as the execution of a method or the handling of an exception.
AOP (Aspect-Oriented Programming) is a programming pattern that increases modularity by allowing the separation of the cross-cutting concern. These cross-cutting concerns are different from the main business logic. We can add additional behavior to existing code without modification of the code itself.
AOP is one of the main components in the Spring framework, it provides declarative services for us, such as declarative transaction management (the famous @Transactional annotation). Moreover, it offers us the ability to implement custom Aspects and utilize the power of AOP in our applications.
The means of choice for a scenario like this is called lookup method injection. In short, this uses the approach of a call to a bean method resulting in a new bean instance created. You'd start by creating a class with an abstract method that will eventually provide the dependency instance:
abstract class MyClient implements Client {
void businessMethod(…) {
Dependency dependency = getDependencyInstance();
…
}
abstract Dependency getDependencyInstance();
}
You now go ahead and configure a prototype bean definition for the dependency:
<bean id="dependency" class="….DependencyImpl" scope="prototype" />
As well as the client using the lookup-method
element to always get a fresh instance of the dependency for each method call:
<bean class="….MyClient">
<lookup-method name="getDependencyInstance" bean="dependency" />
</bean>
This will cause a CGLib proxy being created for MyClient
and the method declaration of getDependencyInstance(…)
being backed by a TargetSource
with a reference to the BeanFactory
and the name of the bean to be looked up. On each method invocation the bean lookup will be triggered and a fresh instance of the prototype configured bean is returned.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With