zoukankan      html  css  js  c++  java
  • 【Spring源码解析】—— 简单工厂模式的BeanFactory的超简版实现

     一、什么是简单工厂模式

    设计模式的核心是“分工”,通过分工将对象与职责划分的更细化,进而提升系统设计的可扩展性,使其更容易维护。

    开闭原则:对扩展开放,对修改关闭;要增加一个新的处理逻辑,可以开一个新的类,不要在老的上面修改

    依赖倒转原则:依赖关系从具体转向抽象,也就是说:A调用B,不是直接调用B的实现,而是依赖B的接口

    迪米特法则:类尽量少的与其他类发生关系,或者产生依赖,以此来使扩展可以更容易

    工厂模式中的三种:简单工厂模式、工厂方法模式、抽象工厂模式;实现了创建者和调用者的分离,调用者不需要知道具体的创建者是什么类,只需要知道工厂的接口以及自己想要的产品名称,就可以进行调用得到想要的产品

    简单工厂模式:简单工厂模式也称为静态工厂模式,工厂类一般采用静态方法,根据接收的参数不同来确定返回对象实例,但简单工厂模式违反了开闭原则,要增加一个新的类别必须要修改代码

    注意,简单工厂模式就是:针对一个项目或者一个独立模块只有一个工厂类,而工厂方法模式是有一组实现了相同接口的工厂类(虽然符合开闭原则,但是会增加新的类来扩展,看情况而定,实际上在项目开发中通常还是用简单工厂比较多)

    二、依据Spring中的BeanFactory自己实现简版

    首先是,先写一个接口类,BeanFactory的接口类如下:

    public interface BeanFactory {
        Object getBean(String beanName);
    }

    下面是xml配置文件 springtest.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans>
    
        <bean id="usertest" class="beanfactory.demo.User">
    
            <property name="username" value="lxlx" />
    
            <property name="passWord" value="111" />
    
            <property name="age" value="11"/>
    
        </bean>
    
    </beans>

    下面是bean定义的class文件 User类:

    public class User {
        private String username;
        private String passWord;
        private int age;
    
        public void setUsername(String username) {
            this.username = username;
        }
    public void setPassWord(String passWord) { this.passWord = passWord; } public void setAge(int age) { this.age = age; } public String getUsername() { return username; } public String getPassWord() { return passWord; } public int getAge() { return age; } }

    接下来是实现类 ConcreteBeanFactory:

    package beanfactory.demo;
    
    
    import org.dom4j.io.SAXReader;
    
    import org.dom4j.*;
    
    import java.io.File;
    
    import java.lang.reflect.Type;
    
    import java.util.HashMap;
    
    import java.util.Map;
    
    import java.util.Iterator;
    
    import java.lang.reflect.Method;
    
    /**
    
     * Created by xiami on 2019/5/26.
    
     */
    
    public class ConcreteBeanFactory implements BeanFactory{
    
    
        private Map<String, Object> beanDefinitionMap = new HashMap<String, Object>();
    
    
        //简单工厂模式的特征是:一个工厂中可以生产多种不同的产品,这里的Bean其实是没有区分不同的bean,是可以通过get返回不同的bean
    
        @Override
    
        public Object getBean(String beanName) {
    
            return beanDefinitionMap.get(beanName);
    
        }
    
    
        //增加一个init的操作方法
    
        //从xml配置文件中进行解析读取
    
        public void init(String xmlPath){
    
            SAXReader saxReader = new SAXReader();
    
            File file = new File(xmlPath);
    
            try {
    
                Document document = saxReader.read(file);
    
                Element root = document.getRootElement();
    
                Element foo;
    
                // 遍历bean
    
                for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
    
                    foo = (Element) i.next();
    
                    // 获取bean的属性id和class
    
                    Attribute id = foo.attribute("id");
    
                    Attribute cls = foo.attribute("class");
    
                    // 利用Java反射机制,通过class的名称获取Class对象
    
                    Class<?> bean = Class.forName(cls.getText());
    
                    // 获取对应class的信息
    
                    java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
    
                    // 获取其属性描述
    
                    java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
    
                    // 设置值的方法
    
                    Method mSet = null;
    
                    // 创建一个对象
    
                    Object obj = bean.newInstance();
    
                    // 遍历该bean的property属性
    
                    for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
    
                        Element foo2 = (Element) ite.next();
    
                        // 获取该property的name属性
    
                        Attribute name = foo2.attribute("name");
    
                        String value = null;
    
                        Object typeValue = null;
    
                        //获取value值
    
                        value = foo2.attributeValue("value");
    
                        for (int k = 0; k < pd.length; k++) {
    
                            if (pd[k].getName().equalsIgnoreCase(name.getText())) {
    
                                mSet = pd[k].getWriteMethod();
    
                                //设置值这里,需要根据类型给value做类型转换
    
                                //properties中包含了properType的项,因为当前程序中就只有String和Int,先处理这样的类型
    
                                Type mType = pd[k].getPropertyType();
    
                                if (mType.getTypeName().equals("java.lang.String")){
    
                                    typeValue = String.valueOf(value);
    
                                }
    
                                else if(mType.getTypeName().equals("int")){
    
                                    typeValue = Integer.parseInt(value);
    
                                }
    
                                mSet.invoke(obj, typeValue);
    
                            }
    
                        }
    
                    }
    
                    // 将对象放入beanMap中,其中key为id值,value为对象
    
                    beanDefinitionMap.put(id.getText(), obj);
    
                }
    
            }catch (Exception e){
    
                System.out.println(e.toString());
    
            }
    
        }
    
    }

    下面是测试类:

    public class Client {
    
        public static void main(String[] args){
    
            AbstractBeanFactory absbf = new AbstractBeanFactory();
    
            absbf.init("E:\java-demo\src\beanfactory\demo\springtest.xml");
    
            User user = (User)absbf.getBean("usertest");
    
            System.out.println("User类的bean有没有创建成功:" + user);
    
            System.out.println("属性值:" + user.getUsername() + "," + user.getPassWord() + "," + user.getAge());
    
        }
    
    }

    测试结果是:

     

    要理解的是:简单工厂模式是一种思想,就是:不针对特定的产品进行工厂的划分,也就是说没有多个批次或者类别的工厂,而是所有的内容都在一个工厂里面生产,你需要什么我给你什么即可

    参考文章:https://blog.csdn.net/mlc1218559742/article/details/52776160/

  • 相关阅读:
    JavaScript--截取字符串
    C#--Dictionary字典学习
    根据条件把A表数据更新到B表中一个字段中(查询更新)
    zip多文件的压缩下载和解压
    C# 创建一个新的DataTable,并根据查询的DataTable结果进行重新赋值
    C# string.formate() 中 如何使用string 循环出来的一串字符
    asp.net mvc 之jqgird 列表数据 根据字典显示中文
    asp.net mvc 之显示24小时折线对比数据
    hightchart扇形图asp.net mvc 实现
    hightchart单个柱状图实现之asp.net mvc
  • 原文地址:https://www.cnblogs.com/keke-xiaoxiami/p/10934406.html
Copyright © 2011-2022 走看看