dynamic constructor injection in spring - java

I am learning Spring Core. I am facing some problem.
As in constructor injection, values are passed through xml file which contains bean definition.
I want to define the bean in xml file and want to initialized the bean with dynamic value passed by the user. Is it possible to create bean with dynamic value by using constructor injection ? What are the various ways to do this?

You can't.
You would have to refactor and inject a provider/factory of your required class, ie add a level of abstraction. You can then call this provider/factory with your required values and get an appropriate instance.

Related

Optional bean registration in bean method without annotations

How can I omit bean registration directly inside a bean method on certain conditions, not with Annotations?
My use case:
I generate child contexts with varying properties for services. (OpenFeign -> ClientConfiguration Contexts)
I want to look up a couple of different settings like 'my.service.default', 'my.service.group', 'my.service.subgroup', 'my.service.name' and merge them. If the merged result satisfies a couple of constrains, I want to provide a MySpecialConfigurationProperty as Bean.
Other beans define ConditionalOnBean(MySpecialConfigurationProperty.class) and can setup all the beans I need.
Now, my issue is with the MySpecialConfigurationProperty bean.
I know, I could define a custom #Condition Annotation. But this would need to replicate the property build logic and I don't want to do it twice.
Instead I'd like to return an Optional.empty() or something like a EmptyBeanRegistration that basically tells Spring: "Don't include this bean. It's fine."
Alternatively, is there a way to send context from the condition to the bean method, so i'm still not building up everything twice?
It's not allowed to return null from a bean method.
I could write a BeanFactoryPostProcessor, but it seems overcomplicated and I wondered, if there is a simple solution, ideally a special return type.

What will happen if I tried to instantiate spring bean manually

Reading some source code and I stumbled upon this spring bean
#Service
public class ValidationService {...}
Which is instantiated manually using the new() operator in many places
ex:
var validationService=new ValidationService();
Now I am thinking to refactor all of these instantiations and replace it with proper spring injection.
It made me think about what would happen if we instantiated a bean using the new() operator. Will it create a new instance of the bean or will it just retrieve the spring managed instance ?
When the object is instantiated manually, it acts like a normal Java object.
Spring is not involved, so all the "spring features" (Inversion of control, dependency injection, etc..) not available.

How can I use #Value or autowire Environment in a class with private constructor?

I have a use case where I am using a utility class (class which contains methods that are all static and the constructor is also private). Therefore, I am not creating the object of the class, I am just accessing the methods with the class name. So, in the utility class I want to access the application.properties. But neither #Value nor autowiring Environment works. It always returns null.
Is there a way to access fields in application.properties in a utility class? I searched for it a lot, but I didn’t find any references.
That's the problem with static classes and fields. Their creation is not in the hands of the Spring or any other dependency injection framework. Thus, Dependency injection frameworks can't inject any value into it.
You can access beanManager and read the value or post initialize your values when spring boot is initialized. Still, your value is null while the Spring boot initialization process is in progress.
Better yet define a Singleton bean using Spring #Scope("singleton").
Change your class to a normal one and let its lifecycle and creation be managed by Spring, you will make it easier to test cuz testing static classes is not always easy.

How to inject spring bean (prototype scope) dynamically

I'm using Spring 3.1.1 and in my business logic, I have a loop which requires a new instance of a spring bean (prototype scope) for each iteration.
What is the best method to do this? Must I create my own BeanFactory class which I can inject once into my class, and call upon it every time to produce the bean upon request? When looking at the Spring 3 docs, it seems to imply that I should use ApplicationContext instead. However, using ApplicationContext makes my code Spring dependent.
What is the best method for something like this? Does Spring already provide a factory of sorts that I can leverage?
ApplicationContext is the factory. You don't have to inject it into your class; you instantiate one and use it to create the beans and wire up their dependencies.
I don't understand the comment "using ApplicationContext makes my code Spring dependent." Yes, it does. Do you think DI is worth it or not?
I think you should go with spring. Spring facilitates your need. You can use a method to lookup bean of specific type from application context. So if you make that bean to be prototype. then when you call this special method, you will be returned with a new instance of the bean you want.
You will find it indetails here!
You can use custom scope and make the injecting bean proxy, and on the custom scope bean listen to some dynamic events that can inject the underling proxy bean

In simple layman's terms what does getBean do in Spring?

Consider a line of code like this
AutomobileDriver ad=(AutomobileDriver)appContext.getBean("increaseSpeed");
Assume there is an IncreaseSpeed class which inherits from AutomobileDriver class
What does getBean do? What is the main function of this?
In "simple layman's terms":
This assumes that Spring was told to create an object instance (possibly in an XML config file) that is identified (by Spring) as with the id "increaseSpeed" and has a class or parent class of AutomobileDriver.
You are asking the Spring context for a reference to (a) by default, the previously created object (this is called a singleton) or (b) a new instance of that object (prototype).
In Spring, you can define a bean and give it an id. Usually, Spring would prefer that you use dependency injection to access the bean. However, Spring provides getBean as another way to access a bean by its id.
Basically, your code will return an instance of the bean with id "increaseSpeed".
This code is requesting the bean named increaseSpeed from the Spring Application Context. Think of the application context as the pool of available objects, which has been configured from your Spring configuration XML. When the application context is started, it creates the beans in the configuration. This call simply asks for the one which is already there. The application context returns this "bean" as a java.lang.Object so you have to cast it to the appropriate type.
You might see this call as an entry point in a Spring application. This call is needed to get the first object out from the application context - from there, this object may have links to other objects which have been injected by Spring.
A bean is a component that provides some functionality, the name of the bean indicates that it would be increase speed.
Those components are registered in a context called 'application context' and can be looked up by name. So if you want to increase the speed look at your apps-context for something that could do this.
More tecnical:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/

Categories

Resources