一、什么是简单工厂模式

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

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

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

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

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

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

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

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

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

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

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

  1. <?xml version="1.0" encoding="UTF-8"?>
  2.  
  3. <beans>
  4.  
  5. <bean id="usertest" class="beanfactory.demo.User">
  6.  
  7. <property name="username" value="lxlx" />
  8.  
  9. <property name="passWord" value="111" />
  10.  
  11. <property name="age" value="11"/>
  12.  
  13. </bean>
  14.  
  15. </beans>

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

  1. public class User {
  2. private String username;
  3. private String passWord;
  4. private int age;
  5.  
  6. public void setUsername(String username) {
  7. this.username = username;
  8. }
  9. public void setPassWord(String passWord) {
  10. this.passWord = passWord;
  11. }
  12.  
  13. public void setAge(int age) {
  14. this.age = age;
  15. }
  16.  
  17. public String getUsername() {
  18. return username;
  19. }
  20.  
  21. public String getPassWord() {
  22. return passWord;
  23. }
  24.  
  25. public int getAge() {
  26. return age;
  27. }
  28. }

接下来是实现类 ConcreteBeanFactory:

  1. package beanfactory.demo;
  2.  
  3. import org.dom4j.io.SAXReader;
  4.  
  5. import org.dom4j.*;
  6.  
  7. import java.io.File;
  8.  
  9. import java.lang.reflect.Type;
  10.  
  11. import java.util.HashMap;
  12.  
  13. import java.util.Map;
  14.  
  15. import java.util.Iterator;
  16.  
  17. import java.lang.reflect.Method;
  18.  
  19. /**
  20.  
  21. * Created by xiami on 2019/5/26.
  22.  
  23. */
  24.  
  25. public class ConcreteBeanFactory implements BeanFactory{
  26.  
  27. private Map<String, Object> beanDefinitionMap = new HashMap<String, Object>();
  28.  
  29. //简单工厂模式的特征是:一个工厂中可以生产多种不同的产品,这里的Bean其实是没有区分不同的bean,是可以通过get返回不同的bean
  30.  
  31. @Override
  32.  
  33. public Object getBean(String beanName) {
  34.  
  35. return beanDefinitionMap.get(beanName);
  36.  
  37. }
  38.  
  39. //增加一个init的操作方法
  40.  
  41. //从xml配置文件中进行解析读取
  42.  
  43. public void init(String xmlPath){
  44.  
  45. SAXReader saxReader = new SAXReader();
  46.  
  47. File file = new File(xmlPath);
  48.  
  49. try {
  50.  
  51. Document document = saxReader.read(file);
  52.  
  53. Element root = document.getRootElement();
  54.  
  55. Element foo;
  56.  
  57. // 遍历bean
  58.  
  59. for (Iterator i = root.elementIterator("bean"); i.hasNext();) {
  60.  
  61. foo = (Element) i.next();
  62.  
  63. // 获取bean的属性id和class
  64.  
  65. Attribute id = foo.attribute("id");
  66.  
  67. Attribute cls = foo.attribute("class");
  68.  
  69. // 利用Java反射机制,通过class的名称获取Class对象
  70.  
  71. Class<?> bean = Class.forName(cls.getText());
  72.  
  73. // 获取对应class的信息
  74.  
  75. java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean);
  76.  
  77. // 获取其属性描述
  78.  
  79. java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors();
  80.  
  81. // 设置值的方法
  82.  
  83. Method mSet = null;
  84.  
  85. // 创建一个对象
  86.  
  87. Object obj = bean.newInstance();
  88.  
  89. // 遍历该bean的property属性
  90.  
  91. for (Iterator ite = foo.elementIterator("property"); ite.hasNext();) {
  92.  
  93. Element foo2 = (Element) ite.next();
  94.  
  95. // 获取该property的name属性
  96.  
  97. Attribute name = foo2.attribute("name");
  98.  
  99. String value = null;
  100.  
  101. Object typeValue = null;
  102.  
  103. //获取value值
  104.  
  105. value = foo2.attributeValue("value");
  106.  
  107. for (int k = 0; k < pd.length; k++) {
  108.  
  109. if (pd[k].getName().equalsIgnoreCase(name.getText())) {
  110.  
  111. mSet = pd[k].getWriteMethod();
  112.  
  113. //设置值这里,需要根据类型给value做类型转换
  114.  
  115. //properties中包含了properType的项,因为当前程序中就只有String和Int,先处理这样的类型
  116.  
  117. Type mType = pd[k].getPropertyType();
  118.  
  119. if (mType.getTypeName().equals("java.lang.String")){
  120.  
  121. typeValue = String.valueOf(value);
  122.  
  123. }
  124.  
  125. else if(mType.getTypeName().equals("int")){
  126.  
  127. typeValue = Integer.parseInt(value);
  128.  
  129. }
  130.  
  131. mSet.invoke(obj, typeValue);
  132.  
  133. }
  134.  
  135. }
  136.  
  137. }
  138.  
  139. // 将对象放入beanMap中,其中key为id值,value为对象
  140.  
  141. beanDefinitionMap.put(id.getText(), obj);
  142.  
  143. }
  144.  
  145. }catch (Exception e){
  146.  
  147. System.out.println(e.toString());
  148.  
  149. }
  150.  
  151. }
  152.  
  153. }

下面是测试类:

  1. public class Client {
  2.  
  3. public static void main(String[] args){
  4.  
  5. AbstractBeanFactory absbf = new AbstractBeanFactory();
  6.  
  7. absbf.init("E:\\java-demo\\src\\beanfactory\\demo\\springtest.xml");
  8.  
  9. User user = (User)absbf.getBean("usertest");
  10.  
  11. System.out.println("User类的bean有没有创建成功:" + user);
  12.  
  13. System.out.println("属性值:" + user.getUsername() + "," + user.getPassWord() + "," + user.getAge());
  14.  
  15. }
  16.  
  17. }

测试结果是:

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

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

【Spring源码解析】—— 简单工厂模式的BeanFactory的超简版实现的更多相关文章

  1. spring源码解析——2容器的基本实现(第2版笔记)

    感觉第二版写的略潦草,就是在第一版的基础上加上了新的流行特性,比如idea,springboot,但是,潦草痕迹遍布字里行间. 虽然换成了idea,但是很多截图还是eclipse的,如果不是看了第一版 ...

  2. 【Spring源码解析】—— 委派模式的理解和使用

    一.什么是委派模式 委派模式,是指什么呢?从字面含义理解,委派就是委托安排的意思,委派模式就是在做具体某件事情的过程中,交给其他人来做,这个事件就是在我的完整链路上的一部分,但是复杂度较高的情况下或者 ...

  3. 【Spring源码解析】—— 策略模式在Spring中的应用

    一.         什么是策略模式 策略模式的定义/含义:策略本身就是为了实现某一个目标而采取的一种工作方式,因此只要能够达成目标,则采取哪一种策略都可以:因此多种实际的策略之间是相互平行的. 注意 ...

  4. Spring源码解析 - AbstractBeanFactory 实现接口与父类分析

    我们先来看类图吧: 除了BeanFactory这一支的接口,AbstractBeanFactory主要实现了AliasRegistry和SingletonBeanRegistry接口. 这边主要提供了 ...

  5. spring 源码解析

    1. [文件] spring源码.txt ~ 15B     下载(167) ? 1 springн┤┬вио╬Ш: 2. [文件] spring源码分析之AOP.txt ~ 15KB     下载( ...

  6. Spring源码解析——循环依赖的解决方案

    一.前言 承接<Spring源码解析--创建bean>.<Spring源码解析--创建bean的实例>,我们今天接着聊聊,循环依赖的解决方案,即创建bean的ObjectFac ...

  7. Spring源码解析系列汇总

    相信我,你会收藏这篇文章的 本篇文章是这段时间撸出来的Spring源码解析系列文章的汇总,总共包含以下专题.喜欢的同学可以收藏起来以备不时之需 SpringIOC源码解析(上) 本篇文章搭建了IOC源 ...

  8. Spring源码解析之ConfigurationClassPostProcessor(二)

    上一个章节,笔者向大家介绍了spring是如何来过滤配置类的,下面我们来看看在过滤出配置类后,spring是如何来解析配置类的.首先过滤出来的配置类会存放在configCandidates列表, 在代 ...

  9. Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean

    Spring源码解析之八finishBeanFactoryInitialization方法即初始化单例bean 七千字长文深刻解读,Spirng中是如何初始化单例bean的,和面试中最常问的Sprin ...

随机推荐

  1. 图学java基础篇之集合工具

    两个工具类 java.utils下又两个集合相关_(准确来说其中一个是数组的)_的工具类:Arrays和Collections,其中提供了很多针对集合的操作,其中涵盖了一下几个方面: 拷贝.填充.反转 ...

  2. Java面试——多线程面试题总结

    )两者都在等待对方所持有但是双方都不释放的锁,这时便会一直阻塞形成死锁. //存放两个资源等待被使用 public class Resource { public static Object obj1 ...

  3. exkmp略解

    推导 ext[i]表示母串s[i..lens]和子串t[1..lent]的最长公共前缀. nxt[i]表示t[i..lent]和t[1..lent]的最长公共前缀. 假设ext[1..k]已经算好,现 ...

  4. hdu3366 Count the string

    考虑dp[i]代表前缀s[1...i]出现的次数,必定有dp[nxt[i]] += dp[i] 倒着推就是了 #include <iostream> #include <cstrin ...

  5. laravel5.2总结--本地化以及常量的使用

    1.本地化 Laravel 的本地化功能提供方便的方法来获取多语言的字符串,让你的网站可以简单的支持多语言. 语言包存放在 resources/lang 文件夹的文件里.每一个子目录应该对应一种语言 ...

  6. 【POI 2010】反对称 Antisymmetry

    题目: 对于一个 $0/1$ 字符串,如果将这个字符串 $0$ 和 $1$ 取反后,再将整个串反过来和原串一样,就称作「反对称」字符串.比如 $00001111$ 和 $010101$ 就是反对称的, ...

  7. Linux之ubuntu系统操作学习笔记

    1,swp分区:当内存不够时用swp分区顶替内存 2,语言环境检查  locale –a:可以明白系统支持什么语言 3,安装软件: apt-cache search(软件):搜索软件 apt-cach ...

  8. MFC录制音频和播放音频

    一.录制音频 在windows中提供了相应的API函数(waveIn这个族的函数)实现录音功能:在使用这些函数时,一定要引入相应的头文件 #include <windows.h> #inc ...

  9. python 使用入的坑

    如测试代码,并没有将li.li_ 的交集查询出来 li=[1,2,3,4,5] li_=[2,5,6,7,9] for i in li_: if i in li: li_.remove(i) prin ...

  10. py2exe error: [Errno 2] No such file or directory: 'MSVCP90.dll'

    使用 python setup.py py2exe 打包时出现 py2exe error: [Errno 2] No such file or directory: 'MSVCP90.dll' 解决方 ...