简体   繁体   中英

Error in creation of bean while using @Required and @Autowired

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:

@Required

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 through autowiring .


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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM