Spring 3 bean instantiation sequence - java

Is there anyway to specify order in which beans to be instantiated? i.e. I want specific beans to be instantiated before other beans, its like startup sequence.
I am using Spring 3.2 and annotation based declaration method.

If bean A depends on bean B by defining <property/>, #Autowired or <constructor-arg/> then the order is forced and fixed by the Spring container. No problem here.
But if you want to enforce specific order of bean creation which is not expressed via explicit dependencies feel free to use:
<bean id="A" depends-on="B"/>
<bean id="B"/>
or better (with annotations, works also with #Bean Java configuration):
#Service
#DependsOn("B")
public class A {}
or even better... don't use it. These constructs are a code smell and often suggest you have some nasty invisible dependency between your components.

Agreed with the answer provided by Tomasz. If you know that bean A depends on bean B then this is right approach.
Sometimes you have logic that should be executed before all beans instantiation. In this case you can use BeanFactoryPostProcessor. Spring creates and executes BeanFactoryPostProcessors first and after that only all other beans. At the same time if your BeanFactoryPostProcessor depends on some bean A you can use property or constructor injection. In this case Spring will create bean A first, then your BeanFactoryPostProcessor, call BeanFactoryPostProcessor and after that only instatiate all other beans in the context.

You can use the Ordered interface on your bean to define ordering relative to other beans.

Further,if you use BeanFactoryPostProcessor as emamedov said, Ordered interface can be implemented to control BeanFactoryPostProcessor instance sequence.

Related

How to inject fields in bean-methods?

Sonar-linter think that right way to inject is:
#Bean
public Example example(DataSource datasource) {
return new Example(datasource)
}
but if only one method's using this field. I'm curious, why exactly one method? And maybe better do #Autowired?
Quote from Sonar's rule:
When #Autowired is used, dependencies need to be resolved when the class is instantiated, which may cause early initialization of beans or lead the context to look in places it shouldn't to find the bean. To avoid this tricky issue and optimize the way the context loads, dependencies should be requested as late as possible. That means using parameter injection instead of field injection for dependencies that are only used in a single #Bean method
As your Quote says, #Autowired needs the dependency to be resolved when the class is Initialzed. Parameter Injection instantiates the bean only when it‘s needed. This increases the effectivity of your Code.
The reason for the Single Method is caused by lifecycle of a Bean. By default Beans are singletons which means they are Shared like static Objects. So if multiple Objects will use the bean it is more effective to inject them with autowired because the possibility That it will be used is much higher and so you provide the Shared instance at Startup

spring autowired vs resource

So my question why did #javax.annotation.Resource worked but #AutoWired did not. For a test on a Restful controller, I was trying to inject MappingJackson2HttpMessageConverter with #Autowired, on start up the container failed to find a qualifying bean even though that class was on the path. Now, to solve this I went into a context xml file and added the bean:
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
Then in the test class had member variable:
#javax.annotation.Resource(name="jsonConverter")
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
Then spring finds the bean. Does Autowire only work for beans that were identified as beans by package scan?
Thanks ahead of time.
Autowired and Resource merely make the class types of annotated field, method or constructor eligible for dependency injection - it does not automatically add those types to the context of your Spring application!
So, as you suspect, in order for the annotations to work, you have to ensure that the auto-wired types are available in the application context yourself, e.g. with the Component annotation and package scan or by explicitly defining the bean in your application-context.xml as you did in your example.
In both cases Spring wires the dependency only when the bean getting wired is defined into spring context. You have to either define the bean in xml file or use annotation based bean definition to make it eligible for wiring.
On the other note, #Resource does name based wiring whereas #Autowire by default goes with type based.
Please see #Resource vs #Autowired for more context on topic.
This is from Spring reference. The second para may provide pointers.
If you intend to express annotation-driven injection by name, do not
primarily use #Autowired, even if is technically capable of referring
to a bean name through #Qualifier values. Instead, use the JSR-250
#Resource annotation, which is semantically defined to identify a
specific target component by its unique name, with the declared type
being irrelevant for the matching process.
As a specific consequence of this semantic difference, beans that are
themselves defined as a collection or map type cannot be injected
through #Autowired, because type matching is not properly applicable
to them. Use #Resource for such beans, referring to the specific
collection or map bean by unique name.
#Autowired applies to fields, constructors, and multi-argument
methods, allowing for narrowing through qualifier annotations at the
parameter level. By contrast, #Resource is supported only for fields
and bean property setter methods with a single argument. As a
consequence, stick with qualifiers if your injection target is a
constructor or a multi-argument method.
I think, in your case, there could be some issue with the default autowiring by name. So I guess Spring would be able to #Autowire the bean if you mention the qualifier. But then again if it is a case for #Resource, I think I'd prefer using it.

When is injected bean actually initialized?

I have the following scenario in my code base:
//this bean, which will be injected,
//is not annotated
public class HelperUtil {
//only default constructor with no args
public void doThis(String _in) {
//...
}
public void doThat() {
//...
}
}
In the below class we do the injection:
#Named
#Stateless
public class BusinessManager {
#PersistenceContext(unitName = "default")
private EntityManager em;
#Inject
private HelperUtil helperUtil ;
//...
}
Q1: When is the instance of HelperUtil which will be injected actually initialized by calling the default constructor? Is it done when the first client into which it is injected (like BusinessManager) is instantiated when the app server (in my case JBoss) starts (and that one will be initialized by the container because it is annotated as #Stateless)?
Q2: In the above exhibit, will HelperUtil remain a singleton as long as no client other than the container asks for an instance by calling the constructor directly and not obtaining an instance via DI?
Q3: What is the advantage of using DI and #Inject in this case vs. simply calling the constructor directly (HelperUtil helper = new HelperUtil();)?
It depends, but you can control these event to execute some code, for example:
If you need that your bean is executed when the app start you need to add #Startup annotation to your bean.
If you need to initialize your bean without access to other injected resources you can use the normal constructor.
If you need some method to be executed when the bean is initialized then use the #PostConstruct annotation in the method.
You need to remember that the creation depends on the scope of the bean, in you case, which is a stateless bean, the bean will be created if some client injects it and there are no other instance available, if is singleton then will bean created just once, in general the bean will be created when they are needed (a singleton bean initialize until the first client uses it, or at startup with the annotation)
EDIT:
For the third question, the advantage is that if you use a resource, or other bean inside your HelperUtil, they will be initialized with the proper values, for example, if you use an entity manager, or other beans inside your helper. If your helper will handle just things like static methods or other simple utilities then you are right, the advantage is none and you could simply manage like an static helper class, but if you need EE resources the you need the bean to be managed in order to get all injections and resources loaded
EDIT 2:
After some more years programming and using dependency injection in Java and C# Core, I can add: The question 3 is very open, using DI will allow your code to:
be less coupled, if you change your constructor, you then would have to go searching all the new ObjectModified(oldParams) to add the new parameters
more easy to test, because you can inject "fake objects" as dependencies, avoiding the need to load all the system and prepare the state for the test, for example, if you want to check some code that depends on the current hour, you could connect a fake provider in test mode to give always the same hour, or some sequence
Avoid cyclical dependency, where class A depends on B and B depends on A, normally this is more complex, like
ClasssA -> ClasssB -> ClasssC -> ClasssA
When this dependencies are present, you can start a modification, then modify the class that uses it, and so on... until somehow you find yourself modifying the same class as before!, so you start in a cycle because the communication path between your objects are complex.
When you use DI, this cycles can be detected early on, so you can rethink your architecture to avoid this productivity blackholes
DI is a very powerful tool to keep big projects maintainable, is now present in a lot of environments and frameworks because is very useful, if this still does not convince you, you can try start a project in Spring boot, PlayFramework, Net Core, Java EE, Ruby on Rails.... and many others that have include this as the normal flow and build a medium size app, then try without DI
Background: Everything within CDI operates within a Context. That being said
A managed bean's fields are instantiated, on request. From the spec:
When the container creates a new instance of a managed bean, session bean, or of any other Java EE component class supporting injection, the container must:
Initialize the values of all injected fields. The container sets the value of each injected field to an injectable reference.
What this means is that the first initialization of a dependent bean is when it's first called for, which is when the parent bean is initialized. Now, the JSF #ApplicationScoped has the eager="true" attribute, which allows beans of that scope to be initialized before they're needed by any other part of the application, on startup, EJB #Startup for the same effect on EJBs. CDI beans however, don't have that capability out of the box.
The default scope of CDI beans is #Dependent. What this means is that an injected bean inherits the scope of the injection target (except when the bean has its own scope; in that case, its own scope applies). In your case, HelperUtil is not going to live beyond the lifetime of that EJB, sorta like #RequestScoped
Related
how is the #RequestScoped bean instance provided to #SessionScoped bean in runtime here?
Non-lazy instantiation of CDI SessionScoped beans
JSF Named Bean, Eager application scoped (aka #ManagedBean(eager=true) )
I think its constructor is not called until the method is called like helperUtil.dothat(), its not when its containing bean is instantiated.
About all of the injected fields must be initialized by the container when the managed beans are instantiated like the other answer, its true, but all of the injected fields are injected with proxies so they are not the real objects so the real constructors aren't called.
If its constructor is called when its containing bean is instantiated then how about a #RequestScoped bean inside a servlet for example. The servlet is only instantiated one time but the injected #RequestScoped bean must be instantiated multiple times. If its true then surely the #RequestScoped annotation wouldn't work.
So by simply looking at those CDI annotations intention and name like "request" or "session", we know that the real CDI managed bean objects are made/ instantiated independent of the containing user bean instantiation.

Is there a way to get all beans with scope prototype that are injected via #Autowired?

Injecting bean with scope prototype with #Autowired usually doesn't work as expected. But when writing code, it's easy to accidentally inject a prototype.
Is there a way to get a list of all #Autowired fields and methods and to match that with a Spring AppContext to check for this?
One approach could be to override org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor(which is responsible for processing #Autowired, #Inject, #Resource etc) and perform the checks that you have mentioned in this overridden bean post processor. However, AutowiredAnnotationBeanPostProcessor gets registered with quite a few of the common custom namespaces (context:component-scan, context:annotation-config etc), so these custom annotations will have to be replaced with the corresponding bean variation and the overridden post processor also registered as a bean.

Dependency injection in Spring. not convenient regarding to prototype scope

Spring's DI works fine for singleton scope bean. However, regarding to prototype scope it is not convenient if the prototype bean itself will inject other beans. The thing is for prototype bean, I would like to create them using new keyword of Java with runtime constructor arguments which is hard to be statically described in XML bean configuration. Using new keyword makes the prototype bean out of Spring container, it is impossible to use Spring DI in them of course.
I am wondering how people solve problem like this? Of course I can use AspectJ to do myself injection as a compensation. But having two injection mechanisms is not an elegant solution to me.
You should be able to create prototype objects through context.getBean(name) or context.getBean(class) where context is ApplicationContext instance.
Another, perhaps even more convenient way is to use factory pattern with factory object being a singleton with all dependencies wired in and passing them to the constructed objects in factory.createInstance(...).
Mark you prototype bean with #Configurable
Spring allows for passing constructor values to the getBean() method, check out this SO-Post:
spring bean with dynamic constructor value
Furthermore, what would be wrong about retrieving a bean from the context, that is just partially initialized and you are setting the runtime-parameters yourself via setters?
Be aware, that Spring-Beans are by default Singletons, so in your Spring-Config you would have to explicitely specify them as being prototype-scoped!

Categories