1

我正在尝试一个 java 应用程序,它有两个通过 Spring 获取的 bean,一个按名称检索,一个自动装配。这是该代码:

package firstspring;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class FirstSpring
{
  private final static Logger logger = LoggerFactory.getLogger(FirstSpring.class);

  @Autowired
  private Car currentCar;
  public void setCurrentCar(Car car) { this.currentCar = car; }
  public Car getCurrentCar() { return currentCar; }

  private static void say(String message) { System.out.println(message); }

  public static void main(String[] args)
  {
    FirstSpring firstSpring = new FirstSpring();
    firstSpring.go();
  }

  public void go()
  {
    logger.info("here we go");
    ApplicationContext appContext = new ClassPathXmlApplicationContext("/appContext.xml");
    Car firstCar = (Car)appContext.getBean("firstCar");

    say ("firstCar was " + firstCar.getColor());
    say ("currentCar is " + currentCar.getColor());

  }

}

及其配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" 
       xsi:schemaLocation=
            "http://www.springframework.org/schema/beans 
                 http://www.springframework.org/schema/beans/spring-beans.xsd
                 http://www.springframework.org/schema/context
                 http://www.springframework.org/schema/context/spring-context-2.5.xsd">

      <context:annotation-config/>

    <bean id="firstCar" class="firstspring.Car">
        <property name="color" value="blue" />
        <property name="doors" value="2" />
        <property name="transmission" value="automatic" />
    </bean>

    <bean id="currentCar" class="firstspring.Car" >
        <property name="color" value="red" />
        <property name="doors" value="4" />
        <property name="transmission" value="5-speed" />
    </bean>

    <bean id="firstSpring" class="firstspring.FirstSpring">
            <property name="currentCar" ref="currentCar" />
    </bean>

</beans>

而 Car 类只是为了使它完整:

package firstspring;

public class Car
{
  String  color;
  int     doors;
  String  transmission;

  public String getColor() { return color; }
  public void setColor(String color) { this.color = color; }

  public int getDoors() { return doors; }
  public void setDoors(int doors) { this.doors = doors; }

  public String getTransmission() { return transmission; }
  public void setTransmission(String transmission) { this.transmission = transmission; }
}

我得到一个空指针异常:

INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5e6458a6: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,firstCar,currentCar,firstSpring,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
Exception in thread "main" java.lang.NullPointerException
    at firstspring.FirstSpring.go(FirstSpring.java:33)
    at firstspring.FirstSpring.main(FirstSpring.java:23)
firstCar was blue

我已经尝试过其他各种事情——将“byName”放在配置中的 currentCar bean 上,但根据我阅读的文档,我认为这没有必要。我在这里想念什么?

4

1 回答 1

3

当您说 时new FirstSpring(),您正在创建自己的该类的实例,该实例不在 Spring 的控制范围内,因此 Spring 无法自动装配它。因此,当您到达 时currentCar.getColor()currentCar为空。为了使其正常工作,您需要ApplicationContext在 main 方法中创建您的,FirstSpring从 Spring 获取实例,然后调用go()它而不是自己创建对象。

简而言之,Spring 不能也不会管理(即自动装配、初始化、销毁等)任何不是它自己创建的对象。*

*除非您使用带有字节码编织的 AspectJ来完成此操作,但这是一个您可能还不想触及的相当高级的主题,除非您对 AspectJ 有其他经验。

于 2013-03-03T15:21:25.287 回答