I am new to spring.I am trying to make use
@Required
@Autowired
org.springframework.beans.factory.BeanCreationException
public class StudentAuto
{
@Autowired
private String name;
@Autowired
private String city;
public String getCity() {
return city;
}
@Required
public void setCity(String city) {
this.city = city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config></context:annotation-config>
<bean id='stu' class='com.bean.StudentAuto' >
</bean>
<bean name='name' class='java.lang.String'>
<constructor-arg value="nm"></constructor-arg>
</bean>
<bean name='city' class='java.lang.String'>
<constructor-arg value="ci"></constructor-arg>
</bean>
</beans>
public class TestApp {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context=new ClassPathXmlApplicationContext("spring.xml");
StudentAuto auto=context.getBean("stu", StudentAuto.class);
System.out.println(auto.getCity());
System.out.println(auto.getName());
}
}
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'stu' defined in class path resource [spring.xml]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanInitializationException: Property 'city' is required for bean 'stu'
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1079)
at com.bean.TestApp.main(TestApp.java:14)
Caused by: org.springframework.beans.factory.BeanInitializationException: Property 'city' is required for bean 'stu'
at org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.postProcessPropertyValues(RequiredAnnotationBeanPostProcessor.java:149)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1074)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
... 7 more
The javadoc for @Required
states
Marks a method (typically a JavaBean setter method) as being 'required': that is, the setter method must be configured to be dependency-injected with a value.
Note that the annotated method is not necessarily a setter but that is usually what it is.
@Required
methods are processed by RequiredAnnotationBeanPostProcessor
which states that
This neatly pushes responsibility for such checking onto the container (where it arguably belongs), and obviates the need (in part) for a developer to code a method that simply checks that all required properties have actually been set.
So the purpose is to guarantee that properties are set by checking if the container has actually invoked the method.
The typical pattern is
class Foo {
private String value;
@Required
public void setValue(String value) {
this.value = value;
}
}
with a bean definition
<bean class="Foo" id="fooBean">
<property name="value" value="some value"/>
</bean>
If you had not added the <property>
, the container would complain and throw exceptions, just like it does with your configuration
<bean id='stu' class='com.bean.StudentAuto' >
</bean>
Here, the container is not using the @Required
method to set the property. It is using reflection on the Field
directly because of @Autowired
. Therefore the @Required
annotation is not validated.