容器工厂(原型&单例)

上一篇讲的是容器工厂的原型。

我们可以不必通过new关键之创建实例,可以直接取容器里面的实例。

我们可以发现,在对比他们的地址值的时候,他们是相同的为true。

如果我们需要的是不一样的呢。也就是有一些特殊的操作需要到的是单例地址。

下面让我们看看如何创建一个可以随意切换原型&单例的容器工厂吧。

我们在上一篇原型的容器工厂上稍微做一下改造就OK了!

添加一个描述bean的类,封装了配置文件bean的类

public class Definition {
    //bean的唯一标识
    private String id;
    //bean的完整类名
    private String className;
    //bean的创建方式
    private String scope = "singleton";

    public String getId() {
        return id;
    }

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

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getScope() {
        return scope;  
    }

    public void setScope(String scope) {
        this.scope = scope;
    }
}

第二,我们需要在容器工厂的类里面做出稍稍的改动。

如下:

public class ContainerFactoryTwo {
    //单例的容器(Singleton)
    private static Map<String,Object> singleton = new HashMap<String,Object>();

    //原型的容器(prototype)
    private static Map<String,Definition> prototype = new HashMap<String,Definition>();

    //初始化
    public ContainerFactoryTwo(String resourcePath){
        initPrototype(resourcePath);
        initSingleton();
    }

    public void initPrototype(String resourcePath){
        //创建SAX解析器
        SAXReader reader = new SAXReader();

        try {
            Document document = reader.read(Thread.currentThread().getContextClassLoader().getResourceAsStream(resourcePath));
            Element root = document.getRootElement();
            List<Element> list = root.elements();
            for (Element e:list){
                String id = e.attributeValue("id");
                String className = e.attributeValue("class");
                String scope = e.attributeValue("scope");
                //构建bean的定义
                Definition def = new Definition();
                def.setId(id);
                def.setClassName(className);
                if(scope!=null){
                    def.setScope(scope);
                }
                prototype.put(id,def);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 初始化单利容器
     */

    private void initSingleton(){
        //遍历prototype里面的值做出判断
        for (String key : prototype.keySet()) {
            Definition def = prototype.get(key);
            //如果是判断是否是singleton
            if("singleton".equals(def.getScope())){
                try {
                    //将实例化对象保存到singleton的map里
                    singleton.put(key, Class.forName(def.getClassName()).newInstance());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
    public Object getBean(String name){
        return getContainerBean(name);
    }

    public <T> T getBean(String name, Class<T> clazz){
        return (T)getContainerBean(name);
    }

    private Object getContainerBean(String name){
        //获取作用域属性
        String scope = prototype.get(name).getScope();
        try {
            //三目运算,singleton在scope里面?是的话就之前前者(K对应的已经是一个Object对象)否则执行后者,通过类加载返回一个对象
            return ("singleton".equals(scope))?singleton.get(name):
                    Class.forName(prototype.get(name).getClassName()).newInstance();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

测试:

public class Main {
    public static void main(String[] args) {
        //创建工厂
        ContainerFactoryTwo factory = new ContainerFactoryTwo("beans.xml");

        Phone phone1 = factory.getBean("OppoPhone", Phone.class);//singleton
        Phone phone2 = factory.getBean("OppoPhone", Phone.class);//singleton

        Pad pad1 = (Pad) factory.getBean("OppoPad", Pad.class);//prototype
        Pad pad2 = (Pad) factory.getBean("OppoPad", Pad.class);//prototype
        System.out.println(phone1==phone2);
        System.out.println(pad1==pad2);
        //phone1.call();
    }
}

结果为:

true

false

注意:在XML文件里面的scope

决定单例或者是原型容器在于Map

时间: 2024-08-07 10:02:40

容器工厂(原型&单例)的相关文章

编程常用设计模式详解--(上篇)(工厂、单例、建造者、原型)

参考来自:http://zz563143188.iteye.com/blog/1847029 一.设计模式的分类 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 二.设计模式的六大原则 1

Spring容器-ApplicationContext的单例设计

Spring容器-ApplicationContext的单例设计 每次通过new创建一个ApplicationContext容器,都会执行refresh方法,看源代码了解到这个refresh方法会重新加载配置文件,并且这个创建的容器对象持有一个所有singleton类型bean的map集合,从而实现单例,而且这个map对象的生命周期和容器对象的生命周期是一样的 如果我们每次都通过new一个容器对象,那么每次都要重新加载配置文件,都要重新生成这个singleton bean的集合,这样所谓的单例就

简单工厂和单例的一些事

一:简单工厂(使用计算器例子进行描述概括) 定义:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类或接口.简单工厂模式又称为静态工厂方法(Static Factory Method)模式,属于类的创建型模式,通常根据一个条件(参数)来返回不同的类的实例. 效果如图所示: //父类 public abstract class Operation { public double NumberA { get; set; } public double NumberB { get;

编程经常使用设计模式具体解释--(上篇)(工厂、单例、建造者、原型)

參考来自:http://zz563143188.iteye.com/blog/1847029 一.设计模式的分类 整体来说设计模式分为三大类: 创建型模式.共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.訪问者模式.中介者模式.解释器模式. 二.设计模式的六大原则 1

C#中的简单工厂和单例

下面首先来说说简单工厂 举个例子: 首先是父类 public abstract class Pizza { public abstract string Info(); } } 子类 public class CheesePizza:Pizza { public override string Info() { return "您好,奶酪比萨成功订购"; } } 下一个子类 public class PGPizza:Pizza { public override string Info

设计模式:简单工厂和单例工厂

1 <?php 2 /** 3 * 纯粹工厂类 4 */ 5 /*class Factory { 6 public static function getOBJ($class_name) { 7 include_once './'.$class_name.'.class.php'; 8 return new $class_name; //可变类 9 } 10 } 11 */ 12 13 /** 14 * cun工厂类 15 */ 16 class Factory { 17 /* 18 生产单例对

简单工厂和单例

简单工厂 定义:专门创建一个类负责创建其他类的实例,被创建的实例都有相同的父类或借口. 代码展示 简单工厂类 public static 父类 Instance(string oop) { 父类 oop = null; switch (cale) { case "+" : cale = new Add(); break; case "-" : cale = new nub(); break; } return cale; } 注意: 01:要用 static 来修饰

简单工厂与单例

单例模式和工厂方法可以说是在软件设计模式中目前用得比较多的,目前在公司做的项目也经常会接触到,他们都实现了类的创建封装,让代码维护变得更加简单.      首先说单例模式,单例模式可以保证整个系统中一个类只有一个实例,而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源,如果只希望在系统中某个类的对象有且只能存在一个,单例模式是最好的解决方案.      对于某些系统来说,有些类只有一个实例很重要,如最常见的数据库连接配置对象.它在整个系统中只需要一个就足够了,多了就会产生很多不必要的

设计模式——工厂和单例

一.工厂模式(以计算器为例) 1.一个运算的类,我们要为他拓展,不能在该类里面进行拓展,要在其外面在写一个子类继承他,对该子类进行方法的增加,以此来拓展这个运算类 <?php class YunSuan { public $a; public $b; public function Suan() { } } class Jia extends YunSuan { public function Suan() { return $this->a+$this->b; } } 2.工厂模式就是