zoukankan      html  css  js  c++  java
  • 容器工厂(原型&单例)

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

    我们可以不必通过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

  • 相关阅读:
    学习日记(2.19 BP神经网络完整代码解读)
    学习日记(2.18)
    学习日记2.17
    学习日记(2.15---2.16)
    最后的作业
    C++第五次作业
    第四次作业:结对编程
    C++第四次作业
    第三次作业:原型设计
    conda基本操作
  • 原文地址:https://www.cnblogs.com/javaLin/p/7906434.html
Copyright © 2011-2022 走看看