I am new to spring.I am trying to make use @Required
and @Autowired
in my code but its giving me org.springframework.beans.factory.BeanCreationException
.Below is my code.
1) StudentAuto.java
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;
}
}
2)spring.xml
<?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>
3)TestApp.java
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());
}
}
and error stack trace is below.
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
Please help me on this issue.
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.
1. DOC:
This annotation simply indicates that the affected bean property must be populated at configuration time, through
an explicit property value in a bean definition
or throughautowiring
.
2. Please pay attention:
@Required
annotation is used for validation checking, not for dependency injection.
3. A way to fix:
As the error log shows: Property 'city' is required for bean 'stu'
. So, you should add a propery tag into the stu
bean - inject city
manually :
<bean id="stu" class="com.bean.StudentAuto">
<property name="city" value="London"/>
</bean>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.