现在想把以前项目中用到单例的地方都改成从spring配置文件中读取。碰到这样的情况:
public class ClassA{
   protected ClassA() {
       loadDatas();
   }
 public static void loadDatas()
   {
       //初始化函数中也需要从spring中获取一个单例对象获取数据
       DataService dataService=(DataService)SpringUtils.getBean("DataService");
       dataService.loadDatas();
       ......
    }
}情况如上,在ClassA的构造函数中调用的初始化函数也需要从spring中抓取bean来执行数据库业务操作。而DataService以前也是单例模式(以前是:DataService.getInstance().loadDatas这种执行模式,我给改成配置在spring里面,然后执行时用getBean拿出该bean来调用其方法)。在spring中配置:
    <!-- DataService -->
    <bean id="DataService" class="com.service.DataService"></bean>
    <!-- ClassA -->
    <bean id="ClassA" class="com.ClassA"></bean>启动程序,发现报错:
Error creating bean with name 'ClassA',Constructor threw exception; nested exception is java.lang.NullPointerException。 这个错误就是在ClassA中调用loadDatas报的。这个错误怎么解决呢?

解决方案 »

  1.   

    把DataService作为ClassA的一个属性,注入进去应该就可以了。
    不过还需要确保dataService.loadDatas()中没有用到spring bean
      

  2.   

    把你的代码改改试试public class ClassA{  private DataService dataService;
      
      //setter 方法,注入使用
      public settDataService(DataService dataService){
           this.dataService=dataService;  //默认构造方法
      public ClassA(){
          dataService.loadDatas();
       }
      }
    }
    bean中的配置文件: <!-- DataService -->
      <bean id="dataService" class="com.service.DataService"></bean>  <!-- ClassA -->
      <bean id="ClassA" class="com.ClassA">
         <property name="dataService" ref="dataService"
      </bean>
      

  3.   

    1、spring托管bean 需要一个默认的无参的public的构造函数,
    Error creating bean with name 'ClassA',Constructor threw exception
    说的是创建classA的时候发生异常,因为没有找到构造器;
    2、DataService dataService=(DataService)SpringUtils.getBean("DataService");
    你的springUtils是自己new的一个context容器?建议不要这么做,因为这样会产生2个ApplicationContext容器。
    如果你需要在初始化的时候执行某些方法,可以在bean的配置中指定initmethod=‘XX’,spring在初始化这个bean后会调用指定的这个初始化方法,
    另外你也可以创建spring的监听器,
    implements ApplicationListener
    public void onApplicationEvent(ApplicationEvent event) {
    /** 当spring容器初始化或者刷新时 */
    if (event instanceof ContextRefreshedEvent) {
                              doSomething();
                     }
    如果使用spring的监听器,必须要让spring托管这个监听器,也就是必须配置到xml中,或注解注入,
    spring会自动把事件发布到监听器中;
      

  4.   

    另外spring托管的 bean里,只要你不指定scope=prototype
    那么创建的bean就是单例的,
    容器里是用一个map来实现单例的,就是beanName(id)与实例(Object)的一对一关系,只会有一个