【问题标题】:Child bean is not found by the spring containerspring 容器找不到子 bean
【发布时间】:2021-03-10 05:49:49
【问题描述】:

我在运行时遇到问题。 我有下面的spring bean定义,当我启动Tomcat服务器时,“student”被加载但子bean“address” 属性没有被注入(我相信基本上找不到“地址”bean),它的值将始终为空,这就是为什么在运行时抛出 NPE。 但是,如果我对“地址”属性使用 @Autowired 注释而不是在 XML 中添加它,它总是可以工作的。

如果我不使用@Autowired,你能告诉我为什么在运行时找不到“地址”吗?解决办法是什么,这样容器才能找到那个bean 在加载“学生”之前?

注意:以下定义在 2 个不同的 XML 中。此外,我在启动期间使用详细记录了类名,并且在这两种情况下都看到了(有和没有@Autowired) “com.test.Address”类正在加载,这就是为什么我认为在 @Autowired 的情况下,容器能够通过检查类型来加载该对象

<bean id="student" class="com.test.Student">
    <property name="address" ref="address" />
</bean>

<bean id="address" class="com.test.Address">
    <property name="street" value="Street1" />
    <property name="state" value="State1" />
    <property name="country" value="Country1" />
</bean>

类定义:

public class Student {

private Address address;

    public setAddress(Address address) {
    this.address = address;
    }
}


public class Address {

private String street;
private String state;
private String country;

public setStreet(String street) {
    this.street = street;
    }
    
public setState(String state) {
    this.state = state;
    }
    
public setCountry(String country) {
    this.country = country;
    }
}

谢谢

【问题讨论】:

  • 能否提供com.test.Addresscom.test.Student的源码?
  • @MarkBramnik 添加了类定义
  • 如何加载应用程序上下文?如果你使用ClassPathXmlApplicationContext ,它会从xml加载,如果你使用AnnotationConfigApplicationContextConfigurableApplicationContext,你可以使用@Autowired

标签: java spring dependency-injection


【解决方案1】:

您已将 Address 作为 Student bean 的 setter 属性。所以在Student类中,需要设置Addreess,如下

public class Student {
    private Address address; // keep same name address as in bean
    public void setAddress(Address address) {
        this.address= address;
    }
}

在此之后,无论你在哪里使用 Student 作为@Autowired student,你都会得到地址。

【讨论】:

    【解决方案2】:

    如果您不使用@Autowired,则必须加载applicationContext.xml

    public class ExploreSpringXmlApplication {
        public static void main(String[] args) {
            try (ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml")) {
                Student s = applicationContext.getBean(Student.class)
    

    但如果您想使用@Autowired,您可以使用AnnotationConfigApplicationContext 加载上下文。

    @Configuration
    @PropertySource("classpath:application.properties")
    @ComponentScan({"the packages of your beans"})
    public class ExploreSpringApplication {
        public static void main(String[] args) {
            try (AnnotationConfigApplicationContext applicationContext =
                         new AnnotationConfigApplicationContext(ExploreSpringApplication.class)) {
    

    或者如果你正在使用spring boot:并且想使用@Autowired

    @SpringBootApplication
    @ComponentScan({"the packages of your beans"})
    public class ExploreSpringBootApplication {
        public static void main(String[] args) {
    ConfigurableApplicationContext applicationContext = 
    SpringApplication.run(ExploreSpringBootApplication.class, args)) {
    

    【讨论】:

      【解决方案3】:

      以下示例对我有用(普通弹簧,没有弹簧靴):

      
      public class Student {
          private Address address;
      
          public void setAddress(Address address) {
              this.address = address;
          }
      }
      
      public class Address {
          private String street;
          private String state;
          private String country;
      
          public void setStreet(String street) {
              this.street = street;
          }
      
          public void setState(String state) {
              this.state = state;
          }
      
          public void setCountry(String country) {
              this.country = country;
          }
      }
      
      
      public class Main {
          public static void main(String[] args) {
              ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("/example/spring.xml");
              Student s = ctx.getBean(Student.class);
              System.out.println(s);
              ctx.close();
          }
      }
      

      Spring定义xml(放在src/resources/example/spring.xml):

      <?xml version = "1.0" encoding = "UTF-8"?>
      
      <beans xmlns = "http://www.springframework.org/schema/beans"
             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">
          <bean id="student" class = "example.Student">
              <property name="address" ref="address"/>
          </bean>
          <bean id="address" class="example.Address">
              <property name="street" value="Street1" />
              <property name="state" value="State1" />
              <property name="country" value="Country1" />
          </bean>
      </beans>
      

      所以看起来像是配置错误,可能是 spring jar 版本的冲突等 - 简而言之,问题中没有出现。

      请注意,使用 XML 配置 bean 确实已经过时,真正的现代应用程序不应该真正使用这种方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-10
        • 1970-01-01
        • 2018-12-13
        • 2018-10-01
        • 1970-01-01
        • 2017-12-13
        相关资源
        最近更新 更多