开发者

Springs XmlBeanFactory is deprecated

I try to learn Spring. I am following this site h开发者_Go百科ttp://www.roseindia.net/spring/spring3/spring-3-hello-world.shtml

I tried one example in that. I am using some what like below, but here it shows:

The type XmlBeanFactory is deprecated

What do I have to use as an alternative to this?

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();
    }
}


ApplicationContext is a sub-interface of BeanFactory.You can use this way

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


Here is the substitute code,

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();
}


BeanDefinitionRegistry beanDefinitionRegistry = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanDefinitionRegistry);
reader.loadBeanDefinitions(new ClassPathResource("SPRING_CONFIGURATION_FILE"));


You can use the ClassPathXmlApplicationContext class.


New way to get beans context (without class casting):

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

When starting an apppication-wide context one should use

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


how about this:

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


Here is the best way to implement

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;


Alternative to XMLBeanFactory found on Spring documentation

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");


Use "FileSystemXmlApplicationContext" as

ApplicationContext  context =  new FileSystemXmlApplicationContext("SpringHelloWorld.xml");

Spring3HelloWorld myBean= (Spring3HelloWorld) context.getBean("Spring3HelloWorldBean");

myBean.sayHello();


There is a warning "Resource leak: 'context' is never closed" with the accepted answer.

The solution suggested in the SO post Spring ApplicationContext - Resource leak: 'context' is never closed fixes the issue.

Hope it helps someone.


I recognized a huge difference between the ApplicationContext and the XmlBeanFactory regarding to the runtime initialization of the objects.

The applicationcontext calls the object constructors immediatly thus creating the objects at once.

The XmlBeanFactory creates an object only if the beanFactory.getBean(String name) is called.

If this is important for the problem domain give the following code a try as an equivalent to the origin source avoiding 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();

To make Captain Obvious satisfied a full example with comparasion follows.

First there is the model 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 + "]";
    }
}

Then the object data in the 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>

And the main method who calls the objects.

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"));
    }

}

The interssting part is the comparasion when the constructor is loaded with the output "calling Employee constructor" in the console output.

--- 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]


I tried the following code

    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();
    }
}

and it works

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜