理解Spring的Bean工厂

本文介绍Spring框架中的Bean工厂实现原理,包括工厂方法模式与抽象工厂模式的区别,以及Spring如何通过自定义BeanFactory接口和实现来读取XML配置文件并创建Bean实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一提到工厂,我们先来回忆前面学习过的工厂方法和抽象工厂模式:

工厂方法:针对产品维度,可以产生新的产品,也可以产生新的产品工厂,既可以扩展产品维度。但是如果我们想在普通工厂上生产产品系列,就会特别麻烦如果产生Apple你就得产生AppleFactory,如果产生Mushroom,就得产生MushroomFactory.这样就会照成工厂泛滥。

抽象工厂:针对产品系列,可以在谋一系列的产品上进行扩展。缺点是如果产生产品新种,改动就会很多。

Spring工厂:可以在产品系列方面既能扩展,又能确定产品品种。下面是Spring的实例:

1.首先定义一个接口两个类:

public class Car implements Moveable {  
    public void run(){
        System.out.println("O(∩_∩)O哈哈~,开着敞篷车回家咯~~~~~");
    }
}
public class Train implements Moveable {
    @Override
    public void run() {
        System.out.println("呜呜呜~~,只能挤火车 ~~~");     
    }
}
public interface Moveable {
    void run();
}

2.添加引用Spring的Jar包 ,添加XML文件:applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="v" class="com.tgbstd.spring.factory.Car"></bean>
</beans>

3.测试类:

    public static void main(String[] args) throws Exception {
        BeanFactory f = new ClassPathXmlApplicationContext("applicationContext.xml");   
        Object o =f.getBean("v");  //传入id
        Moveable m =(Moveable)o; 
        m.run();
    }
}

Spring利用本身读取XML配置文件,并且实现了BeanFactory接口。我们只需要在客户端传入配置文件名,传入配置文件的ID,就能根据Id找到相应的class产生的对象,并将对象作为一个bean反馈回来。

上面是封装好的一个Spring,那么我们如何来模拟Spring的原理呢?
Spring模拟:定义一个BeanFactory,在这个里面有自己的实现,最常见的实现ClassPathXML ,从这里面读XML,把读到的信息都装在一个MAP里面,当你要的时候再拿出来。
A.定义BeanFactory接口和getBean方法

public interface BeanFactory {
    Object getBean(String id);  

}

B.定义自己的实现:创建读取XML文件类,ClassPathXmlApplicationContext。前面一篇文章已经介绍了如何读取XML文件,这里就不再赘述,直接看实例吧。

public class ClassPathXmlApplicationContext implements BeanFactory {

    //把所有配置文件里的东西读出来保存在map里面
    private Map<String,Object> container = new HashMap<String,Object>();

    //定义构造函数
    public ClassPathXmlApplicationContext(String fileName) throws Exception {

        SAXBuilder sb = new SAXBuilder();
        Document doc = sb.build(this.getClass().getClassLoader()
                .getResourceAsStream(fileName));   //拿到配置文件
        Element root = doc.getRootElement();
        List list = XPath.selectNodes(root, "/beans/bean");   

        // 循环遍历节点
        for (int i = 0; i < list.size(); i++) {
            Element bean = (Element) list.get(i);
            String id = bean.getAttributeValue("id");
            String clazz = bean.getAttributeValue("class");
            Object o =Class.forName(clazz).newInstance();

            container.put(id, o); //存放对象

            //相关过程输出
            System.out.println("id=" + id);
            System.out.println("通过id拿到具体的class信息:" +"class");

        }
    }

    @Override
    //调用getBean将拿到的信息返回给客户
    public Object getBean(String id) {
        return container.get(id);       

    }

}

在ClassPathXmlApplicationContext类的构造方法中,有一个文件名,通过fileName指向配置文件,就能从配置文件读取信息了。并且把所有从配置文件读出来的信息,存储在map容器里。

C.测试类


public class Test {
    public static void main(String[] args) throws Exception {
        //父类引用指向子类对象,找到配置文件
        BeanFactory f = new ClassPathXmlApplicationContext("com/tgbstd/spring/factory/applicationContext.xml");
        //传入id
        Object o = f.getBean("v");
        Moveable m =(Moveable)o; 
        m.run();        
    }
}

D.结果:

上面简单的介绍了Spring创建Bean工厂的原理。其实Bean主要是通过自己定义一个BeanFactory工厂的实现,通过构造函数传入初始值,读取XML配置文件信息。并且将读取到的id作为key值,读取到的对象作为Value值,存入到Map容器中。当客户端需要获取时,只要传入id,就能从容器中读取出来。

原文链接:http://m.blog.youkuaiyun.com/article/details?id=38963085

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值