What is the use of RequiredAnnotationBeanPostProcessor in Spring framework? - spring

I am a beginner in Spring framework. I have started learning Spring framework a couple of weeks. I did not get any proper explanation of RequiredAnnotationBeanPostProcessor. Please, someone, help me by giving some example of RequiredAnnotationBeanPostProcessor and where to use this. Thanks in advance.

RequiredAnnotationBeanPostProcessor is a not common used annotation in applications that use Spring.
The #Autowired annotation that provides both the autowiring and the requiring (by default enabled) behaviors is often preferred to.
RequiredAnnotationBeanPostProcessor is a BeanPostProcessor implementation.
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.
In the case of RequiredAnnotationBeanPostProcessor, it enforces required JavaBean properties to have been configured.
Required bean properties are detected through a Java 5 annotation: by default, the Spring's Required annotation.
To be short, it allows to ensure that a bean that declares 'required' properties has actually been configured with values. Note that the value may be null.
For example suppose this model class :
public class Foo {
private Bar bar;
#Required
public void setBar(Bar bar) {
this.bar = bar;
}
}
If setBar() is never invoked during the initialization of the bean, a org.springframework.beans.factory.BeanInitializationException is thrown.
For example this bean configuration will trigger the exception throwing :
#Configuration
public class MyConfig {
#Bean
public Foo getFoo() {
return new Foo();
}
}
Of course if you add #Autowired to setBar() with a resolvable dependency, it will be fine :
public class Foo {
private Bar bar;
#Autowired
#Required
public void setBar(Bar bar) {
this.bar = bar;
}
}
So we could consider that a good use case for RequiredAnnotationBeanPostProcessor is a case where you don't want/cannot specify the autowiring in the class of the bean.
Note also that RequiredAnnotationBeanPostProcessor provides also an additional feature that is according to the javadoc its primary goal :
The motivation for the existence of this BeanPostProcessor is to allow
developers to annotate the setter properties of their own classes with
an arbitrary JDK 1.5 annotation to indicate that the container must
check for the configuration of a dependency injected value.
It means that you may specify another annotation that #Required to indicate the required constraint.
RequiredAnnotationBeanPostProcessor defines indeed a setRequiredAnnotationType() method that you can override to set the annotation to use.
As you can see, the use of RequiredAnnotationBeanPostProcessor is related to very specific corner cases. That's why you probably don't find many examples about it.

Related

Difference between #Autowired and #Required with setter injection in Spring

I know a lot had been written about #Autowired and #Required annotations.
But I have a very basic question as below -
What is the difference between the below two mechanism of setter injection.
I haven't yet got a complete satisafactory answer for this.
The reason is :
1)#Autowired without any extra information like - #Autowired(required=false) is same as #Required
2)What are we gaining from #Required additionally ?
3)Why #Required is recommend over #Autowired on setter injection ?
class MyClass {
private MyService myService;
#Autowired
public void setMyService(MyService val) {
this.myService = val;
}
}
class MyClass {
private MyService myService;
#Required
public void setMyService(MyService val) {
this.myService = val;
}
}
#Autowired is not the same as #Required.
The #Required-Annotation is specialized for telling Spring that this property has to be injected by the information given in the XML-configuration-file (eager) and not through annotations. And that doesn't matter when you use the #Autowire-Annotation.
The #Autowire-Annotation (as in your code-example), tells the ApplicationContext (a.k.a the Spring-IoC-Containter) to inject the desired dependency. (No matter how, if its by using annotations or the XML-File of the ApplicationContext).
The #Required-Annotation, tells the ApplicationContext that this property has to be mentioned in the XML-file (The XML-File of the ApplicationContext), but the Annotation on its own doesn't tell to inject the dependency. So it is used to check if it is in the XML-configuration file, but not to inject a dependency. The injection is done because the property is mentioned in the XML-file.
So in the end it tells that the injection has to be done because of a configuration in the XML-File. But again: The annotation doesn't tell that the dependency has to be injected, but that it has to be mentioned in the XML-File - which then lets the dependency be injected.
With mentioning the property in a XML-File I mean such a configuration for instance:
<bean id="MyClass" class="com.myclasses.common.MyClass">
<property name="someProperty" value="ValueThatHasToBeInjected" />
</bean>
So why should I use it over the #Autowired-Annotation?
You should use it when the dependency has to be injected due to the informatoin given in the XML-configuration file.
Can you give me an example?
Well, there is already a very good example on this website. where this is also explained.
1) You can think of #Required as a check that the property has been eagerly initialised. In other words it requires that it's been injected via configuration (xml or annotation). If annotation is used then you'll see it alongside #Autowired. If the Bean injected does not exist the application fails to startup with a runtime exception.
2) Nothing more nothing less. #Required is very specific in what it's meant to be: a) only applicable on methods, b) requires the bean or else application runtime error on startup. Again, you need dependency injection either via annotation or xml.
3) Most likely you want to know at startup if a Bean is failed to be injected and for that reason you can have #Required along with #Autowired for expressiveness. Functionality-wise you don't need it if you have #Autowired.
Extra notes:
#Autowired has more functionality on the other side of the coin that is - when you want to achieve laziness. So on a setter method:
as you mentioned #Autowired(required = false)
Can also be paired with #Lazy
you can have #Autowired (without required = false) on a setter method whose param is Java 8's Optional achieving the same effect.

What is the magic behind Field #Autowired

I am currently improving my Spring knowledge. I wonder what really happens when I use Spring annotation #Autowire on a field.
Here is a piece of code :
OutputHelper file
#Component
public class OutputHelper {
#Autowired
#Qualifier("csvOutputGenerator")
private IOutputGenerator outputGenerator;
public void setOutputGenerator(IOutputGenerator outputGenerator) {
this.outputGenerator = outputGenerator;
}
// I can focus only on what my code do because my objects are injected
public void generateOutput(){
outputGenerator.generateOutput();
}
}
CsvOutputGenerator file
#Component
public class CsvOutputGenerator implements IOutputGenerator {
public void generateOutput(){
System.out.println("Csv Output Generator");
}
}
Application file
public static void main(String[] args) {
// Create the spring context
ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/spring-module.xml");
// Get the configured OutpuHelper from the spring-module.xml
OutputHelper output = (OutputHelper) context.getBean("outputHelper");
// Display output from the output configured
output.generateOutput();
}
My configuration file just contain <context:component-scan base-package="com.xxx.xxx.output"/>
When I execute this code all work fine. But what makes me surprised is when I delete the setOutputGenerator in OutPutHelper file, my piece of code keeps working. I tought that with this configuration, the OutputHelper was first created with default constructor and initialized with setter.
I expected an error because the variable outputGenerator was not be able to be initialized.
Is anyone can help me to understand ?
The idea to have fields #Autowired is questionable. It works, but it will difficult other aspects of your implementation (i.e. testing).
There are 3 types of injections:
fields - basically configured applying reflection (Field.set(Object, Object)) directly to the field:
#Autowired
private MyInterface field;
setters - with this approach the configuration of each dependency goes through a property (spring goes through all methods and execute each one annotated with #Autowired using Method.invoke(Object, Object...), thus its value is configured using its setter as follows:
#Autowired
public void setField(MyInterface value) {
this.field = value;
}
constructors - the last, and my preferable approach, the constructor injection. That one basically annotates an constructor with #Autowired and instead of using methods or fields, you can configure your bean directly on your constructor. For that spring will elect the a constructor to be used to instantiate your #Component, and it will use an #Autowired if existent or a empty params constructor, invoking it using Constructor.newInstance(Object...). Example:
#Component
public class Implementation {
private MyInterface field;
#Autowired
public Implementation(MyInterface value) {
Assert.notNull(value, "value should not be null");
this.field = value;
}
}
One of the ideas behind Inversion of Control (or Dependence Injection) is to be able to isolate a piece of code in order to provide decent test implementation support.
In order to go deeper, it is necessary to comment that during a unit test you want the class in its isolated form, all you will use with that class are basically mocks for its dependencies (injections).
So, what are the results:
If you do field injection, it will be quite costly to every single time set the beans using some reflection to configure the bean during your tests (another logic needs to be introduced to configure the bean to be tested).
With setter injection approach you will be able to use your own bean to configure it with mocks necessary to isolate your implementation and test its functionality.
And finally, with the constructor injection approach you will have not only the support to configure your bean, but you will be able to require its dependencies. This means that for every new dependency a new parameter on your constructor is added, this brings you come advantages on development time, for example, you will be able to see on development time the unit tests affected with the introduction of that new dependency (once your IDE will point it out for your).
Simple answer
Actually, the setter is useless, since the CDI use java Reflection to access fields.
It means that fields are no longer accessed by method calls.
Reflection allow iterating throught all fields of a class and check if there are annoted with a specific annotation.
In this case, if a field in your class is annoted With #Autowired (or #Inject wich is more J2E complient), the container will iterate throught searching if there is a registered bean that fits the current property.
Going deeper
When you context is starting, the container iterate classes and search all field annoted with #Inject or #Autowired.
For these fields, it search an available bean.
Here is the must simple example :
public class SpringClassInChargeOfDependencyInjection {
public void handdleInjections(T objectWithInjectableField) {
Class<T> clazz = objectWithInjectableField.class;
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class) || field.isAnnotationPresent(Inject.class)) {
//find a bean for the type;
Object injectableBean = getAvailablebean(field.getType());
field.setAccessible(true);
//inject the value into the class, this line explain why the setter is not necessary
field.set(objectWithInjectableField, injectableBean);
}
}
}
}
This is a non-working example just to explain how it works.
Tips
You might consider using #Inject instead of #Autowired, the later was created by Spring, #Inject is a part of the the JSR-330. Spring does understand #Inject as well, you just need to add the javax.inject jar dependency to your project. If later you want to switch from spring to something else (guice for example) you won't have to change all your #Autowired annotations
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

How to set up init-method for a bean when spring is configured by annotation driven?

I use spring roo to build project and it's annotation driven, and there is no bean definition in XML file. All the configuration info is in *.aj file.
And now I want to set up an init method for a bean which don't have a default constructor (that bean is from the third party and it has a constructor with arguments, and I cannot remove them or give a default constructor to it.)
Is there anyone who can tell me how to do this, please?
The reason I want to do this is because I want to use applicationContext.getBean("thatBeanName") to dynamically get the bean and use it. Because the bean don't have a default constructor, I always get the error: java.lang.NoSuchMethodException: com.to.that.bean.<init>() and this is why I want to add the init-method to the bean.
Use #PostConstruct as shown in below example. It is equivalent to init-method="initialize()"
#PostConstruct
public void initialize() {
messages.put("English", "Welcome");
messages.put("Deutsch", "Willkommen");
}
#Bean(initMethod="init")
public MyBean getMyBean() {
...
}
In spring container it is "init" method that being called the last,
#postconstruct called before afterPropertiesSet. so it is safer if someone miss use.
"Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:
1.Methods annotated with #PostConstruct
2.afterPropertiesSet() as defined by the InitializingBean callback interface
A custom configured init() method
[https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-java-lifecycle-callbacks][1]
Although, today I would prefer to be more Spring independent and use either #Postconstract, or even configure default init method recognition. to have only meaningful method name indicate that it should be used for initialization - clear from frameworks, clear from annotations.
As #Pangea has put in , #PostConstruct is the best choice. You could also implement initializingBean and do the initialization in afterPropertiesSet method .Check here for this approach.
I realized that there have been multiple answers trying to solve the problem. But with the newly introduced #Configuration which is popularly used within Spring Boot. Things are changed a little bit.
If you are using #Bean annotation in #Configuration annotated class like:
#Configuration
class FooClass {
#Bean
public Bar bar() {
return new Bar();
}
}
If you want to use an automatically called method on the bean instance during initialization, you have two options below:
Option1:
#Configuration
class FooClass {
#Bean(initMethod="init")
public Bar bar() {
return new Bar();
}
}
Option2:
#Configuration
class FooClass {
#Bean
public Bar bar() {
Bar bar = new Bar();
bar.init();
return bar;
}
}
BUT, as is explain in #Bean Java Doc here:
/**
* The optional name of a method to call on the bean instance during initialization.
* Not commonly used, given that the method may be called programmatically directly
* within the body of a Bean-annotated method.
* The default value is {#code ""}, indicating no init method to be called.
*/
The second is regarded as a better answer. See link here

How do I prevent Spring from instantiating a prototype scoped bean on context refresh?

I am using prototype scoped bean definitions in my Spring XML descriptors to configure the default properties (these beans have many properties) and then I call the application context with a getBean(beanName, ctorArgs[]) to create instances.
The bean definitions require 2-3 constructor arguments that supply logically unique keys used for things like key properties for the JMX ObjectName etc. Additionally, the variables that the constructor arguments are written to are final.
What I am seeing is that when the application context refreshes, it attempts to instantiate these prototypes, which seems completely the opposite of what you want prototypes to do. They're templates, not actual instances. To work around this, I have been configuring the prototypes with bogus ctor values so these bogus bean instances are instantiated and I simply filter out the created MBeans later in the code.
My question is, how do I configure the application context to register these prototype bean definitions, but not instantiate them until I make a getBean call ?
UPDATE:
The problem is a bit more complicated than I initialy thought. In fact, lazy is the default behaviour for prototype-scoped beans. I digged a bit and I managed to reproduce your problem and find the solution. So what is the problem?
You probably have <aop:scoped-proxy/> enabled or (#ComponentScan(scopedProxy=...) equivalent). During context refresh Spring wraps your prototype bean (ClosedMetricSubscriberFeed) with scoped proxy. It uses class proxy because (a) class proxies are chosen or (b) the class has no interfaces.
The class-based proxy is basically a CGLIB subclass of your bean that must call (due to JVM rules) a base class's constructor. And CGLIB generated class always calls no-arg constructor.
I know this sounds complicated, here's what you can do:
Disable <aop:scoped-proxy/>. Just like that.
Provide a dummy no-arg constructor and deprecate it just in case. Unfortunately you will have to discover such bogus instances manunally. Note that in this case the class will be of type: ``.
Extract an interface from your class and use interfaces for scoped proxies:
.
#Scope(
value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.INTERFACES)
Old answer:
Use lazy initialization with #Lazy annotation or lazy-init="true" (see 4.4.4 Lazy-initialized beans in reference documentation) configuration attribute.
<bean id="proto" class="MyPrototype" scope="prototype" lazy-init="true"/>
or:
#Service
#Scope("prototype")
#Lazy
public class MyPrototype {/*...*/}
I use a private, deprecated, no-arg constructor that throws an IllegalStateException. The context loads fine, getBean() with the constructor args works fine, and getBean() without args throws the exception.
package a;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
#Component("myCommand")
#Scope("prototype")
public class Command {
final protected String name;
#Deprecated
private Command() {throw new IllegalStateException("Only for Spring"); }
public Command(String name) {
super();
this.name = name;
}
#Override
public String toString() {
return "Command [name=" + name + "]";
}
}

Autowiring doubts in spring?

After going thru autowiring concept
i have got some questions. These are:-
If i need to autowire below class byType or byName , is it mandatory to have setStudent() method in class College?
public class College {
private Student student1;
private String registration1;
}
<bean id="student1" class="Student"/> - in case of byname it will look into id attribute and in case of bytype it will look for class attribute in above
Stetement. Right? If incase it finds two bean dean tags for the same type it will throw fatal error in case of bytype. Correct?
autodetect Scenario chooses constructor or byType through introspection of the bean class. If a default constructor is found, the byType mode
will be applied.
My question here if default constructor is not found and constructor with argument is found then autowire by constructor
will be applied. Correct?
Do we need to specify #Autowired somewhere in College to apply the autowiring. As i can see this in this example
but nothing is specified here
1), 4) There are two separate ways of autowiring in Spring: XML-based and annotaion-based.
XML-based autowiring is activated from XML config, as described here. In the end, it will call setter method, so setStudent() method is required here.
Annonation-based autowiring, on the other hand, is performed via reflection magic. It attempts to fill everything you mark with #Autowired annotation. In fact, it can set private field with no accessors, as in
public class Foo {
#Autowired private Thingy thing; // No getThing or setThing methods
private void doStuff() {
// thing is usable here
}
}
For #Autowired annotaion to work, you will need to define corresponding bean post-processor; it is done by adding the following line to xml config:
<context:annotation-config/>
Note, that these two autowiring methods are independant, and it is possible(but not recommended) to use them simultaneously. In that case, xml autowiring will override annotations.
2) In general, autowiring will fail, if it cannot find one and only one candidate for injection. So, in your case, it will fail with exception upon container creation. There are some fallback quirks, but in general it works reliably.
3) Yes, documentaion says so.
About byName and byType autowiring. While byName autowiring simply tries to match bean name (can be specified with id attribute), byType is a bit more complex than class attribute lookup. It searches beans by type, and it will match interfaces. Example:
public interface SomeService {
void doStuff();
}
public class SomeServiceImpl implements SomeService {
#Override public void doStuff() {
// Implementation
};
}
public class ServiceUser {
#Autowired
private SomeService someService; // SomeServiceImpl instance goes here
}
P.S. You are referencing two different versions of Spring in your question, 2.5 and 3.0. Autowiring behavior is same in both.
In Addition if you are using #Autwired annotation you need to mark the classes as candidates for autowiring. It should be done by using one of these annotations:
#Repository
#Service
#Component
#Controller
and of cause you can configure it in different scopes:
#Scope("prototype")
#Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}
Hope it makes it more clear.

Resources