Implementation of "Context.getApplicationContext().getBean" - spring

Can anyone explain what happens when we call
ApplicationContext.getApplicationContext().getBean(abcclassName.class)
being the abcclassName being an abstract class.
I understand that an abstract class cannot be instantiated. Then how does this work?

I have never done this with Abstract Classes, but with Interfaces.
What it will do is to get the instance of the subclass defined in your context. In other words if you have a bean of the class Cat (subclass of Animal) defined in your context and you use the class Animal to pass to your ApplicationContext.getBean(). You will get the Cat back.
If you have more than one subclass in your context, it will throw an exception though.
See this for reference: http://docs.spring.io/spring/docs/3.0.x/api/org/springframework/beans/factory/BeanFactory.html#getBean%28java.lang.Class%29

Looking through the source code for DefaultListableBeanFactory -- source -- should answer your question. (Both links are for version 3.0.x, as that is what I found with GrepCode. I imagine that not much has changed in terms of finding the matching beans by a type)
Basically, it takes the class, and looks for Beans in the ApplicationContext that are assignable to the provided type.
The method AbstractBeanFactory#isTypeMatch(String, Class<?>) contains the code that will be of most interest to you, and there is a path that reaches it via the DefulatListableBeanFactory#getBean(Class<?>) method.

After going through Source code Spring 3.0.5 , when you do ApplicationContext.getApplicationContext().getBean(abcclassName.class) on abstract class and if the abstract class is not configured as #component then the AbstractBeanFactory calls the isTypematch method to get the Correct Entity .
Basically it takes all beans ( which ever initiated in context) and iterate one by one and will check that bean is factory for requested or the bean can be assignable for the requested.
if only one bean resolved using that type then it returns that bean if its found multiple beans then it returned error .
return !BeanFactoryUtils.isFactoryDereference(name) &&
typeToMatch.isAssignableFrom(beanInstance.getClass());
The typeToMatch.isAssignableFrom(beanInstance.getClass()); call use Native method in Object class public native boolean isAssignableFrom(Class<?> cls); to check

Related

Spring's BeanFactory getBean method returns JDK proxy when using #Async (with custom thread executor)

I am new to spring and trying to understand the framework. I have a class (say ClassA) which has execute() method. I am using "prototype" scope (#Scope) for this class.I am using #Async("customThreadPoolTaskExecutor) for this execute() method. I have already defined this customThreadPoolTaskExecutor in another class with #Configuration. Then I have another class (say ClassB) which uses BeanFactory of spring to get an object of ClassA using beanFactory.getBean(ClassA).
I am getting an error on this line inside ClassB
ClassA A = (ClassA) beanFactory.getBean(ClassA);
Error is as below
org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'ClassA' is expected to be of type 'ClassA' but was actually of type 'jdk.proxy2.$Proxy103'
Note that above code works fine and returns an object of ClassA if I remove #Async from execute() method of ClassA.
I am looking to understand the root of the problem and clear some of my concepts about spring. What is the relationship between #Async and bean creation using BeanFactory's getBean method. Why does it work without #Async but not with #Async.
Note : The fix/workaround I have so far is to add "ScopedProxyMode" for ClassA as "TARGET_CLASS". After adding this to ClassA's #Scope annotation, things work ok but I am not able to understand the root cause of the issue.

Spring Boot application.properties appear unregistered when accessed from constructor

This is the code that I have:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
public Program() {
System.out.println(appTitle);
}
}
The application.properties has
app.title=The Program
The output is null insteaf of The Program.
So, what am I missing? I have tried several examples; none worked.
Since appTitle is an autowired field, it is not set until after the object is initially constructed. This is why the value is still null in your example. The bean construction process in this scenario is as follows:
The Program constructor is called, creating a new Program instance
The appTitle field is set on the newly constructed bean to ${app.title}
The ideal fix for this depends on your goals. If you truly need the value within the constructor, you can pass it in as an autowired constructor parameter. The value will then be available within the constructor:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
public Program(#Value("${app.title}") appTitle) {
System.out.println(appTitle);
}
}
If you don't need it in the constructor itself, but need it for the proper initialization of the bean, you could alternatively use the #javax.annotation.PostConstruct annotation to make use of it after the object's construction but before it is made available for use elsewhere:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
#PostConstruct
public void printAppTitle() {
System.out.println(appTitle);
}
}
Finally, if you don't need the value at construction time, but need it during the life of the bean, what you have will work; it just won't be available within the body of the constructor itself:
#Component
#Configuration
#PropertySource("application.properties")
public class Program {
#Value("${app.title}")
private String appTitle;
}
Nothing wrong, just don't do it in a constructor...
Other answers on this question are written assuming the goal is creating a Spring-managed bean that uses the given property in its creation. However, based on your comments in another answer, it looks like the question you want answered is how to access an externalized property (one provided by #Value) within a no-argument constructor. This is based on your expectation that a Java inversion of control (IoC) container such as Spring should allow accessing externalized properties (and presumably other dependencies) within a no-argument constructor. That being the case, this answer will address the specific question of accessing the property within a no-argument constructor.
While there are certainly ways this goal could be achieved, none of them would be idiomatic usage of the Spring framework. As you discovered, autowired fields (i.e. fields initialized using setter injection) cannot be accessed within the constructor.
There are two parts to explaining why this is. First, why does it work the way it does, programmatically? Second, why was it designed the way it was?
The setter-based dependency injection section of the Spring docs addresses the first question:
Setter-based DI is accomplished by the container calling setter methods on your beans after invoking a no-argument constructor or a no-argument static factory method to instantiate your bean.
In this case, it means that first the object is created using the no-argument constructor. Second, once the object is constructed, the appTitle is initialized on the constructed bean. Since the field isn't initialized until after the object is constructed, it will have its default value of null within the constructor.
The second question is why Spring is designed this way, rather than somehow having access to the property within the constructor. The constructor-based or setter-based DI? sidebar within the Spring documentation makes it clear that constructor arguments are in fact the idiomatic approach when dealing with mandatory dependencies in general.
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. [...]
The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. [...]
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. [...]
A property needed to construct the object certainly would be categorized as a mandatory dependency. Therefore, idiomatic Spring usage would be to pass in this required value in the constructor.
So in summary, trying to access an application property within a no-argument constructor is not supported by the Spring framework, and in fact runs contrary to the recommended use of the framework.

CDI #Obeserves with default methods

Maybe I'm missing something, but with Java 8 we can have default methods inside an Interface and I`m trying to modify an existing one, adding a new default method that Observes an Event and calls the old method signature at this same Interface, just to avoid code changes in legacy Beans (in this case, all #ApplicationScoped). Ex:
public interface A {
public void oldMehtod(Event evt);
default void newMethod(#Observes Event evt) {
this.oldMehtod(Event evt);
}
}
The "newMethod" is never fired by a Bean that implements this Interface. What I`m missing? Thanks in advance!
From CDI specification, you may want to read more about it then just this quotation:
An observer method is a non-abstract method of a managed bean class or session bean class...
Yours is not a method of a managed bean class. You will need to place that method on an actual bean class to have it discovered.
I cannot tell you exactly why you cannot have them on interfaces but I suppose it's some hard limitation. That would be good question to ask on CDI-dev mailing list.

Faker for Grails gives variable not defined error

I have a Grails 2.4.4 application configured with spring-security-core. I want to generate fake users in the BootStrap using the faker plugin. However when I instantiate the bean fakerService in BootStrap and try using it ie. fakerService.firstname(), I get an error :
ERROR context.GrailsContextLoaderListener - Error initializing the application: Cannot invoke method firstName() on null object
Message: Cannot invoke method firstName() on null object
I'm just a beginner in Grails. Am I doing the Dependency Injection wrong?
http://pasteboard.co/rvbihRU.png
Yes you are :)
A little background. When you add a class-scope variable (a field) in a Groovy class without an explicit scope modifier (e.g. public, private, protected) it defaults to public just like classes and methods. But it is considered a property in the JavaBean sense, so the Groovy compiler creates a getter and a setter for you based on the name. So if you declare def foo and String bar (it doesn't matter whether you specify the type) you'll get Object getFoo(), void setFoo(Object), String getBar(), and void setBar(String) methods (you should decompile a POGO class with a decompiler and see this for yourself - it's pretty cool stuff - I recommend JD-GUI, but use whatever you prefer). If you had declared any of them already Groovy would skip that one and not overwrite yours. This is cool because you can treat the variable like a simple public field, but at any time add getter and/or setter logic and not affect calling clients (Groovy or Java, since the Java classes would have been calling the getter and setter all along, and Groovy calls the getter and setter for you when you read or write a property).
So why am I babbling on about this? Dependency injection is done by Spring - you're injecting Spring beans. There are various ways to do this, but the default in Grails is to use autoinject-by-name. So for any bean registered in the ApplicationContext and special classes like BootStrap, integration tests, etc., Spring scans the methods looking for setters. It strips off "set" and lowercases the next letter, and that's the "property" name of the setter. If there's a bean with that name in the ApplicationContext, Spring will call that setter, passing the bean with that name, and if the types are in sync, your class will have a reference to that bean.
You added a local variable. Nothing special happens to local variables, and Spring doesn't see them, and they're not candidates for dependency injection. Move the declaration to class scope, before the init closure, e.g.
class BootStrap {
def fakerService
def init = {
...
}
}
and the Groovy compiler will add a getFakerService method that isn't of much interest, but also a setFakerService method that Spring will see. It will determine that its property name is "fakerService", see that there is a bean with that name, and call the setter. This all happens before Grails calls the init closure, so at that point the value will be a non-null FakerService eagerly awaiting your calls.

What is the difference between BeanPostProcessor and init/destroy method in Spring?

What is the difference between implementing the BeanPostProcessor interface and either using the init/destroy method attributes in the XML configuration file in Spring or implementing InitializingBean/DisposableBean interface?
This is pretty clearly explained in the Spring documentation about the Container Extension Points.
The BeanPostProcessor interface defines callback methods that you can
implement to provide your own (or override the container's default)
instantiation logic, dependency-resolution logic, and so forth. If you
want to implement some custom logic after the Spring container
finishes instantiating, configuring, and initializing a bean, you can
plug in one or more BeanPostProcessor implementations.
So in essence the method postProcessBeforeInitialization defined in the BeanPostProcessor gets called (as the name indicates) before the initialization of beans and likewise the postProcessAfterInitialization gets called after the initialization of the bean.
The difference to the #PostConstruct, InitializingBean and custom init method is that these are defined on the bean itself. Their ordering can be found in the Combining lifecycle mechanisms section of the spring documentation.
So basically the BeanPostProcessor can be used to do custom instantiation logic for several beans wheras the others are defined on a per bean basis.
Above answers clearly explains some of the very important aspect.
Apart from that it's also important to understand that both beanPostProcessor and init and destroy methods are part of the Spring bean life cycle.
BeanPostProcessor class has two methods.
1) postProcessBeforeInitialization - as name clearly says that it's used to make sure required actions are taken before initialization. e.g. you want to load certain property file/read data from the remote source/service.
2) postProcessAfterInitialization - any thing that you want to do after initialization before bean reference is given to application.
Sequence of the questioned methods in life cycle as follows :
1) BeanPostProcessor.postProcessBeforeInitialization()
2) init()
3) BeanPostProcessor.postProcessAfterInitialization()
4) destroy()
You may check this by writing simple example having sysout and check their sequence.
Init and Destroy callback methods are part of Spring bean life cycle phases. The init method is going to be executed after bean instantiation. Similarly, The destroy method is going to be executed before bean finalization.
We can implement this functionality using implementing interfaces InitializingBean and DisposableBean, or using annotations #postconstruct and #predestroy, or declare the <bean> with init-method and destroy-method attributes.
BeanPostProcessor interface is used for extending the functionality of framework if want to do any configuration Pre- and Post- bean initialization done by spring container.
For Example: By default, Spring will not aware of the #PostConstruct and #PreDestroy annotation. To enable it, we have to either register CommonAnnotationBeanPostProcessor or specify the <context:annotation-config /> in bean configuration file. Here CommonAnnotationBeanPostProcessor is predefined BeanPostProcessor implementation for the annotations. Like:
#Required enables RequiredAnnotationBeanPostProcessor processing tool
#Autowired enables AutowiredAnnotationBeanPostProcessor processing tool
And one more main diff is InitializingBean,DisposableBean related afterPropertiesSet() & destory() methods did not accept any paratmeters and return type also void, so we did not implement any custom logic.
But coming to BeanPostProcess methods postProcessBeforeInitialization(Object bean,String beanName) and postProcessAfterInitilization(Object bean,String beanName) are accept those two paramaters and return type also Object so we are able to write initilzation logics as well as any custom login based on the passing bean...
These both callback method feautes are including the bean life cycle and the following are the life cycle as follows
1) BeanPostProcessor.postProcessBeforeInitilazation()
2) #postConstruct or InitializingBean.afterPropertiesSet() or initialization method which is
defining in xml /* here also it's following the same oredr if three ways are availiable **/
3) BeanPostProcessor.postProcessAfterInitialization()
4) #preDestroy or DisposibleBean.destroy() or destroy method which is defining in xml
/* here also it's following the same oredr if three ways are availiable **/
Just a short supplement to all the answers above: If you have any generic logic, common logic that needs to be universally applied to all your Spring beans, such as the injection of a logger to your beans, setting of a properties file, setting default values to fields of your beans through reflection; you could put that logic into ONE single place: the #Overriden callbacks (eg: postProcessBeforeInitialization(Object arg0, String arg1) if you are implementing the BeanPostProcessor interface); instead of duplicating the same logic across all your beans.
a)The postProcessBeforeInitialization() will be called before initialization of the bean.
b)Once the bean gets initialized, the different callbacks methods are called in the following order as per the Spring docs:
Methods annotated with #PostConstruct
afterPropertiesSet() as defined by the InitializingBean callback interface
init method defined through the XML.
The main difference is that the above 3 methods get called after the initialization get completed by the postProcessBeforeInitialization() method.
Once these methods get completed the method postProcessAfterInitialization() will be called and then the destroy methods are called in the same order:
Methods annotated with #PreDestroy
destroy() as defined by the DisposableBean callback interface
destroy() method defined through the XML.

Resources