1、静态工厂模式
其他对象不能直接通过new得到某个类,而是通过调用getInstance()方法得到该类的对象
这样,就可以控制类的产生过程。
顺带提一下单例模式和多例模式:
  单例模式是指控制其他对象获得该对象永远只有同一个对象
  而多例模式则是根据需要从某个具体集合中获取所需的对象

 import java.util.ArrayList;
import java.util.List; public class Car implements Moveable{
private static Car car = new Car(); //控制其他对象获得该对象永远只有同一个对象
private static List<Car> cars = new ArrayList<Car>(); //多例 //将构造方法私有化,限制其他对象无限制的new出Car对象
private Car(){} //通过静态方法获得new 出的对象
//即在取得该对象的过程由Car本身控制,可以为其添加各类限制
public static Car getInstance(){
//if() if。。。。
return car;
}
public void run(){
System.out.println("the car is running......");
}
}

2、普通工厂模式
与静态工厂不同,普通工厂将产生的过程交由其他的类处理,而并非类的本身。

 public class CarFactory {

     @Override
Moveable create() {
return new Car() ;
}
}

这样就可以通过获得CarFactory的对象,调用create()得到Car对象

3、抽象工厂模式

抽象工厂是指工厂类要产生一个系列的对象,将工厂类进行抽象,这样就可以通过改变工厂类,从而能够改变一系列的对象。
其实這就慢慢接近面向抽象编程。

这里类就比较多,就从抽象程度由上到下进行介绍:
(1)、测试类

 public class Test {
public static void main(String[] args){ AbstractFactory d = new DefaultFactory(); /**
可以通过AbstractFactory d = new NewFactory() 可以替换系类对象
**/ Vehicle v = d.createVehicle();
Food f = d.createFood(); v.run();
f.eat(); }
}

(2)、抽象工厂

 public abstract class AbstractFactory {
public abstract Vehicle createVehicle();
public abstract Food createFood();
}

(3)、抽线工厂实现类

 public class NewFactory extends AbstractFactory{

     @Override
public Vehicle createVehicle() {
return new Plane();
} @Override
public Food createFood() {
return new Banana();
}
}
 public class DefaultFactory extends AbstractFactory{

     @Override
public Vehicle createVehicle() {
return new Car();
} @Override
public Food createFood() {
return new Apple();
}
}

(4)、交通工具抽象类以及实现类

 public abstract class Vehicle {
public abstract void run();
}

******************************

 public class Car extends Vehicle{

     public void run(){
System.out.println("the car is running......");
}
}
 public class Plane extends Vehicle{
@Override
public void run() {
System.out.println("the plane is flying...");
}
}

(5)、食物抽象类以及实现类

 public abstract class Food {
public abstract void eat();
}

*****************************

 public class Apple extends Food{
public void eat(){
System.out.println("eating apple...");
}
}
 public class Banana extends Food{
public void eat(){
System.out.println("eating Banana...");
}
}

普通工厂模式与抽象工厂各有优缺点,
在产生对象系类时,普通工厂会有工厂泛滥的现象
抽象工厂在产生新的对象类型时,从上到下都需要改动

4、Spring的Bean工厂
现在就需要运用工厂知识来模拟Spring的Bean工厂了

我们先看看Spring是如何运用Bean工厂的

(1)、applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="v" class="com.csu.springFactory.Train">
</bean>
<!--类似 一般配置文件的 v="com.csu.springFactory.Car" 的格式--> </beans>

(2)、测试类:

 import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestForSpring {
public static void main(String[] args){
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Object o = factory.getBean("v"); //找到 id = v对应的class, getInstance得到一个Bean对象,返回
Moveable m = (Moveable)o;
m.run(); }
}

Spring 的applicationContext.xml中配置了实体类的信息,通过解析改配置文件,可以得到一个包含了所有类对象的工厂,
然后其他对象通过该工厂对象,调用getBean得到,以id为参数,得到对象

在理解了这些之后,我们就可以开始模拟了,其实最主要的部分就是在于解析xml配置文件,可以通过id获得类名,然后利用
反射得到该类,getInstance()后获得对象。解析xml文件有很对方法,这里就用JDOM.

(1)模拟的配置文件 applicationContext_simulation.xml (简化)

<?xml version="1.0" encoding="UTF-8"?>
<beans> <bean id="v" class="com.csu.springSimulation.Car">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!--类似 spring.properties配置文件的 v="com.csu.springFactory.Car" 的格式--> </beans>

(2)模拟BeanFactory

public interface BeanFactory_simulation { Object getBean(String id); }

(3)模拟BeanFactory的实现类ClassPathXmlApplicationContext_simulation

 import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class ClassPathXmlApplicationContext_simulation implements BeanFactory_simulation{
//要自定义方法解析applicationContext.xml
//Spring 的解析方式为ClassPathXmlApplicationContext("applicationContext.xml"); 这个类就是要模拟ClassPathXmlApplicationContext的功能 private Map<String,Object> container = new HashMap<String, Object>(); //存放所有对象 public ClassPathXmlApplicationContext_simulation(String filename) throws Exception {
SAXBuilder sb=new SAXBuilder();
Document doc=sb.build(this.getClass().getClassLoader().getResourceAsStream(filename));
Element root=doc.getRootElement();
List list=root.getChildren("bean"); System.out.println(list.size()); for(int i=0;i<list.size();i++){
Element element=(Element)list.get(i);
String id=element.getAttributeValue("id");
String clazz = element.getAttributeValue("class"); Object o = Class.forName(clazz).newInstance();
container.put(id,o); } } @Override
public Object getBean(String id) {
return container.get(id);
}
}

(4)测试类

 public class Test {
public static void main(String[] args) throws Exception {
BeanFactory_simulation beanFactory_simulation = new ClassPathXmlApplicationContext_simulation("com/csu/springSimulation/applicationContext_simulation.xml");
Object o = beanFactory_simulation.getBean("v");
Moveable m = (Moveable)o;
m.run();
}
}

这样我们就基本清楚了Spring的Bean工厂的模式了,面向抽象编程,将具体类放在配置文件中。

从基础知识到重写Spring的Bean工厂中学习java的工厂模式的更多相关文章

  1. 在Spring的Bean注入中,即使你私有化构造函数,默认他还是会去调用你的私有构造函数去实例化

    在Spring的Bean注入中,即使你私有化构造函数,默认他还是会去调用你的私有构造函数去实例化. 如果我们想保证实例的单一性,就要在定义<bean>时加上factory-method=” ...

  2. Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题【转】

    Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题 http://blog.didispace.com/Spring-Boot-And-Feign- ...

  3. Spring基础知识1--环境搭建、bean创建、依赖注入、注解注入

    一.Spring两大核心内容 1.控制反转IOC/DI:  应用本身不负责对象的创建和维护,对象和依赖对象的创建完全交给容器管理. 2.AOP(面向切面编程):通过预编译的方式,在运行期通过动态代理的 ...

  4. (spring-第3回【IoC基础篇】)spring的依赖注入-属性、构造函数、工厂方法等的注入(基于XML)

    Spring要把xml配置中bean的属性实例化为具体的bean,"依赖注入"是关卡.所谓的"依赖注入",就是把应用程序对bean的属性依赖都注入到spring ...

  5. Spring在bean配置文件中定义电子邮件模板

    在上一篇Spring电子邮件教程,硬编码的所有电子邮件属性和消息的方法体中的内容,这是不实际的,应予以避免.应该考虑在Spring bean 配置文件中定义电子邮件模板. 1.Spring的邮件发件人 ...

  6. Spring(九):Spring配置Bean(二)自动装配的模式、Bean之间的关系

    XML配置里的Bean自动装配 Spring IOC容器可以自动装配Bean,需要做的仅仅是在<bean>的autowire属性里指定自动装配的模式,模式包含:byType,byName, ...

  7. Redis基础知识之————使用技巧(持续更新中.....)

    一.key 设计技巧 把表名转换为key前缀 如, tag: 第2段放置用于区分区key的字段--对应mysql中的主键的列名,如userid 第3段放置主键值,如2,3,4...., a , b , ...

  8. 【视觉基础知识】Bag of words 在图像中的应用

    文章转载自:https://www.cnblogs.com/shihuajie/p/5782515.html BOW (bag of words) 模型简介 Bag of words模型最初被用在文本 ...

  9. #######【Python】【基础知识】【标准库】目录及学习规划 ######

    下述参考Python DOC https://docs.python.org/zh-cn/3/library/index.html 概述 可用性注释 内置函数 内置常量 由 site 模块添加的常量 ...

随机推荐

  1. ip协议的数据分片备忘

    总结: 不仅tcp协议能对数据段进行分割,ip协议也具备这个功能,之所以会这样是两者都受到底层MTU的限制(虽说tcp是根据MSS限制来分割数据包,由于MTU=tcp包头+ip包头+MSS,所以其实也 ...

  2. 堆排序-C语言实现

    堆排序 堆排序是利用堆的性质进行的一种选择排序.下面先讨论一下堆. 1.堆 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]<=key[2i+1]&&Key[i ...

  3. 解决ajax.net 1.0中文乱码问题!

      在使用ajax.net的UpdatePanel的时候,当requestEncoding编码为GB2312的时候,出现乱码.如果要解决这个问题最简单的就是改用utf-8了,但是原来使用GB2312, ...

  4. 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 7.全局防护盲点的总结上篇

    0x01 背景 现在的WEB应用对SQL注入的防护基本都是判断GPC是否开启,然后使用addlashes函数对单引号等特殊字符进行转义.但仅仅使用这样的防护是存在很多盲点的,比如最经典的整型参数传递, ...

  5. linux连接静态库

    在项目中发现,使用 -l连接某个库时,如果存在同名的静态库(.a)和动态库(.so),默认会连接.so 那么如何指定连接静态库呢?如果有多个库,有些要连接静态库.有些要连接动态库,连接选项该如何指定呢 ...

  6. mongodb 操作语句与sql操作语句对比

    上行:SQL 操作语句 下行:Mongo 操作语句 CREATE TABLE USERS (a Number, b Number) db.createCollection("mycoll&q ...

  7. 【Shell脚本学习11】Shell注释

    以“#”开头的行就是注释,会被解释器忽略. sh里没有多行注释,只能每一行加一个#号.只能像这样: #-------------------------------------------- # 这是 ...

  8. javascript中Math ceil(),floor(),round()三个函数的对比

    Math.ceil()执行的是向上舍入 Math.floor()执行向下舍入 Math.round()执行标准舍入 一下是一些补充: ceil():将小数部分一律向整数部分进位. 如: Math.ce ...

  9. dfa最小化,上一个版本采用的是moore的打表法,这个版本采用的是hopcroft的方法,但是实现中采用链表而不是栈来优化。

    hopcroft法的复杂度,他们说是nlogn,可是都没有严格的证明.难得找到一篇讲的详细点的论文,却又啰里啰唆的,不过那篇论文里面采用的是颜色树这个结构,有点意思. 前面的那个算法是n的平方复杂度, ...

  10. 怒刷DP之 HDU 1087

    Super Jumping! Jumping! Jumping! Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64 ...