【问题标题】:Springs XmlBeanFactory is deprecatedSprings XmlBeanFactory 已弃用
【发布时间】:2011-07-11 00:33:20
【问题描述】:

我尝试学习 Spring。我正在关注这个网站http://www.roseindia.net/spring/spring3/spring-3-hello-world.shtml

我尝试了一个例子。我正在使用一些类似下面的东西,但这里显示:

XmlBeanFactory 类型已弃用

我必须使用什么来替代它?

public class SpringHelloWorldTest {
    public static void main(String[] args) {

        XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("SpringHelloWorld.xml"));

        Spring3HelloWorld myBean = (Spring3HelloWorld)beanFactory.getBean("Spring3HelloWorldBean");
        myBean.sayHello();
    }
}

【问题讨论】:

标签: java spring deprecated xmlbeans


【解决方案1】:

我发现 ApplicationContext 和 XmlBeanFactory 在对象的运行时初始化方面存在巨大差异。

应用程序上下文立即调用对象构造函数,从而立即创建对象。

只有当 beanFactory.getBean(String name) 被调用时,XmlBeanFactory 才会创建一个对象。

如果这对问题域很重要,请尝试以下代码,作为避免 XmlBeanFactory 的原始源的等效代码。

final Resource resource = new ClassPathResource("SpringHelloWorld.xml");
final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
xmlBeanDefinitionReader.loadBeanDefinitions(resource);
Spring3HelloWorld myBean = beanFactory.getBean("Spring3HelloWorldBean", Spring3HelloWorld.class);
myBean.sayHello();

为了让显而易见的船长满意,下面是一个比较完整的例子。

首先是模型 Person.java。

package com.stackoverflow.questions_5231371;

// ./spring-tutorial/src/main/java/com/stackoverflow/questions_5231371/Person.java
public class Person {

    int id;
    String name;

    public Person() {
        System.out.println("calling Employee constructor");
    }

    public int getId() {
        return id;
    }

    public void setId(final int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person [id=" + id + ", name=" + name + "]";
    }
}

然后是personbeans.xml中的对象数据。

<?xml version="1.0" encoding="UTF-8"?>
<!-- ./spring-tutorial/src/main/java/personbeans.xmlxml  -->
<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.xsd">

    <bean id="p1" class="com.stackoverflow.questions_5231371.Person">
        <property name="id" value="1" />
        <property name="name" value="Sheldon" />    
    </bean>

    <bean id="p2" class="com.stackoverflow.questions_5231371.Person">
        <property name="id" value="2" />
        <property name="name" value="Penny" />  
    </bean>

    <bean id="p3" class="com.stackoverflow.questions_5231371.Person">
        <property name="id" value="3" />
        <property name="name" value="Leonard" />    
    </bean>

</beans>

以及调用对象的主要方法。

package com.stackoverflow.questions_5231371;

import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;

// ./spring-tutorial/src/main/java/com/stackoverflow/questions_5231371/Main.java
public class Main {

    public static void main(final String[] args) {
        // Spring #1 IoC application context
        System.out.println("--- ApplicationContext");
        final ApplicationContext context = new ClassPathXmlApplicationContext("personbeans.xml");
        System.out.println("context created ---");
        System.out.println(context.getBean("p1"));
        System.out.println(context.getBean("p2"));
        System.out.println(context.getBean("p3"));

        // Spring #2 IoC bean factory
        System.out.println("--- DefaultListableBeanFactory");
        final Resource resource = new ClassPathResource("personbeans.xml");
        final DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        final XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        xmlBeanDefinitionReader.loadBeanDefinitions(resource);
        System.out.println("bean definition loaded ---");
        System.out.println(beanFactory.getBean("p1"));
        System.out.println(beanFactory.getBean("p2"));
        System.out.println(beanFactory.getBean("p3"));
    }

}

interssting 部分是在控制台输出中加载构造函数与输出“calling Employee constructor”时的比较。

--- ApplicationContext
calling Employee constructor
calling Employee constructor
calling Employee constructor
context created ---
Person [id=1, name=Sheldon]
Person [id=2, name=Penny]
Person [id=3, name=Leonard]
--- DefaultListableBeanFactory
bean definition loaded ---
calling Employee constructor
Person [id=1, name=Sheldon]
calling Employee constructor
Person [id=2, name=Penny]
calling Employee constructor
Person [id=3, name=Leonard]

【讨论】:

    【解决方案2】:

    有一个警告“Resource leak: 'context' is never closed”并接受了答案。

    SO 帖子Spring ApplicationContext - Resource leak: 'context' is never closed 中建议的解决方案解决了该问题。

    希望它可以帮助某人。

    【讨论】:

      【解决方案3】:

      使用“FileSystemXmlApplicationContext”作为

      ApplicationContext  context =  new FileSystemXmlApplicationContext("SpringHelloWorld.xml");
      
      Spring3HelloWorld myBean= (Spring3HelloWorld) context.getBean("Spring3HelloWorldBean");
      
      myBean.sayHello();
      

      【讨论】:

        【解决方案4】:
        BeanDefinitionRegistry beanDefinitionRegistry = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanDefinitionRegistry);
        reader.loadBeanDefinitions(new ClassPathResource("SPRING_CONFIGURATION_FILE"));
        

        【讨论】:

          【解决方案5】:

          Spring 文档中 XMLBeanFactory 的替代品

          GenericApplicationContext ctx = new GenericApplicationContext();
          XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
          xmlReader.loadBeanDefinitions(new 
          ClassPathResource("applicationContext.xml"));
          PropertiesBeanDefinitionReader propReader = new 
          PropertiesBeanDefinitionReader(ctx);
          propReader.loadBeanDefinitions(new 
          ClassPathResource("otherBeans.properties"));
          ctx.refresh();
          
          MyBean myBean = (MyBean) ctx.getBean("myBean");
          

          【讨论】:

            【解决方案6】:

            这个怎么样:

            DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
            XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
            reader.loadBeanDefinitions(new ClassPathResource("config/Beans.xml"));
            Messager msg = (Messager) factory.getBean("Messager");
            

            【讨论】:

              【解决方案7】:

              ApplicationContext是BeanFactory的子接口,可以这样使用

              public class SpringHelloWorldTest {
                  public static void main(String[] args) {
                      ApplicationContext context= new ClassPathXmlApplicationContext("SpringHelloWorld.xml");
                      Spring3HelloWorld myBean= (Spring3HelloWorld) context.getBean("Spring3HelloWorldBean");
                      myBean.sayHello();
                  }
              }
              

              【讨论】:

              • 我猜如果我提供完整路径和文件名它将无法工作,因为 xmlBeanFactory 将作为其构造函数接受 FileSystemResource 的对象。
              • 我们也可以使用AbstractApplicationContext context = new ClassPathXmlApplicationContext("SpringHelloWorld.xml");代替ApplicationContext,因为我们可以使用close()来关闭容器
              • 通过使用AbstractApplicationContext类,我们还可以使用registerShudownHook()方法来保证优雅关闭,并调用可能与bean生命周期相关的相关destroy方法。
              【解决方案8】:

              这是最好的实现方式

              Resource res = new FileSystemResource("beans.xml");
              XmlBeanFactory factory = new XmlBeanFactory(res);
              
              or
              
              ClassPathResource res = new ClassPathResource("beans.xml");
              XmlBeanFactory factory = new XmlBeanFactory(res);
              
              or
              
              ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
                     new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
              // of course, an ApplicationContext is just a BeanFactory
              BeanFactory factory = (BeanFactory) appContext;
              

              【讨论】:

                【解决方案9】:

                获取 bean 上下文的新方法(无类转换):

                BeanDefinitionRegistry beanFactory = new DefaultListableBeanFactory();
                XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
                reader.loadBeanDefinitions(new ClassPathResource("beans.xml"));
                

                当启动应用程序范围的上下文时,应该使用

                ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
                

                【讨论】:

                  【解决方案10】:

                  这是替代代码,

                  public static void main(String[] args){
                      ApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"SpringHelloWorld.xml"});
                      BeanFactory factory=context;
                      Spring3HelloWorld myBean=(Spring3HelloWorld)factory.getBean("Spring3HelloWorldBean");
                      myBean.sayHello();
                  }
                  

                  【讨论】:

                  • 嗨..谢谢它的工作。你能给我一些书和教程来学习弹簧。
                  【解决方案11】:

                  我尝试了以下代码

                      public class Spring3HelloWorldTest {
                      public static void main(String[] args) {        
                          DefaultListableBeanFactory  beanFactory = new DefaultListableBeanFactory ((BeanFactory) new ClassPathResource("SpringHelloWorld.xml"));     
                          Spring3HelloWorld myBean = (Spring3HelloWorld) beanFactory.getBean("Spring3HelloWorldBean");
                          myBean.sayHello();
                      }
                  }
                  

                  它可以工作

                  【讨论】:

                  • 这将失败并出现 ClassCastException,因为资源不是 BeanFactories。
                  【解决方案12】:

                  您可以使用ClassPathXmlApplicationContext 类。

                  【讨论】:

                  • 嗨..谢谢它的工作。你能给我一些书和教程来学习弹簧。
                  猜你喜欢
                  • 2014-02-12
                  • 1970-01-01
                  • 2016-03-03
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-04-20
                  • 1970-01-01
                  相关资源
                  最近更新 更多