从基础知识到重写Spring的Bean工厂中学习java的工厂模式
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的工厂模式的更多相关文章
- 在Spring的Bean注入中,即使你私有化构造函数,默认他还是会去调用你的私有构造函数去实例化
在Spring的Bean注入中,即使你私有化构造函数,默认他还是会去调用你的私有构造函数去实例化. 如果我们想保证实例的单一性,就要在定义<bean>时加上factory-method=” ...
- Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题【转】
Spring Boot和Feign中使用Java 8时间日期API(LocalDate等)的序列化问题 http://blog.didispace.com/Spring-Boot-And-Feign- ...
- Spring基础知识1--环境搭建、bean创建、依赖注入、注解注入
一.Spring两大核心内容 1.控制反转IOC/DI: 应用本身不负责对象的创建和维护,对象和依赖对象的创建完全交给容器管理. 2.AOP(面向切面编程):通过预编译的方式,在运行期通过动态代理的 ...
- (spring-第3回【IoC基础篇】)spring的依赖注入-属性、构造函数、工厂方法等的注入(基于XML)
Spring要把xml配置中bean的属性实例化为具体的bean,"依赖注入"是关卡.所谓的"依赖注入",就是把应用程序对bean的属性依赖都注入到spring ...
- Spring在bean配置文件中定义电子邮件模板
在上一篇Spring电子邮件教程,硬编码的所有电子邮件属性和消息的方法体中的内容,这是不实际的,应予以避免.应该考虑在Spring bean 配置文件中定义电子邮件模板. 1.Spring的邮件发件人 ...
- Spring(九):Spring配置Bean(二)自动装配的模式、Bean之间的关系
XML配置里的Bean自动装配 Spring IOC容器可以自动装配Bean,需要做的仅仅是在<bean>的autowire属性里指定自动装配的模式,模式包含:byType,byName, ...
- Redis基础知识之————使用技巧(持续更新中.....)
一.key 设计技巧 把表名转换为key前缀 如, tag: 第2段放置用于区分区key的字段--对应mysql中的主键的列名,如userid 第3段放置主键值,如2,3,4...., a , b , ...
- 【视觉基础知识】Bag of words 在图像中的应用
文章转载自:https://www.cnblogs.com/shihuajie/p/5782515.html BOW (bag of words) 模型简介 Bag of words模型最初被用在文本 ...
- #######【Python】【基础知识】【标准库】目录及学习规划 ######
下述参考Python DOC https://docs.python.org/zh-cn/3/library/index.html 概述 可用性注释 内置函数 内置常量 由 site 模块添加的常量 ...
随机推荐
- ip协议的数据分片备忘
总结: 不仅tcp协议能对数据段进行分割,ip协议也具备这个功能,之所以会这样是两者都受到底层MTU的限制(虽说tcp是根据MSS限制来分割数据包,由于MTU=tcp包头+ip包头+MSS,所以其实也 ...
- 堆排序-C语言实现
堆排序 堆排序是利用堆的性质进行的一种选择排序.下面先讨论一下堆. 1.堆 堆实际上是一棵完全二叉树,其任何一非叶节点满足性质: Key[i]<=key[2i+1]&&Key[i ...
- 解决ajax.net 1.0中文乱码问题!
在使用ajax.net的UpdatePanel的时候,当requestEncoding编码为GB2312的时候,出现乱码.如果要解决这个问题最简单的就是改用utf-8了,但是原来使用GB2312, ...
- 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 7.全局防护盲点的总结上篇
0x01 背景 现在的WEB应用对SQL注入的防护基本都是判断GPC是否开启,然后使用addlashes函数对单引号等特殊字符进行转义.但仅仅使用这样的防护是存在很多盲点的,比如最经典的整型参数传递, ...
- linux连接静态库
在项目中发现,使用 -l连接某个库时,如果存在同名的静态库(.a)和动态库(.so),默认会连接.so 那么如何指定连接静态库呢?如果有多个库,有些要连接静态库.有些要连接动态库,连接选项该如何指定呢 ...
- mongodb 操作语句与sql操作语句对比
上行:SQL 操作语句 下行:Mongo 操作语句 CREATE TABLE USERS (a Number, b Number) db.createCollection("mycoll&q ...
- 【Shell脚本学习11】Shell注释
以“#”开头的行就是注释,会被解释器忽略. sh里没有多行注释,只能每一行加一个#号.只能像这样: #-------------------------------------------- # 这是 ...
- javascript中Math ceil(),floor(),round()三个函数的对比
Math.ceil()执行的是向上舍入 Math.floor()执行向下舍入 Math.round()执行标准舍入 一下是一些补充: ceil():将小数部分一律向整数部分进位. 如: Math.ce ...
- dfa最小化,上一个版本采用的是moore的打表法,这个版本采用的是hopcroft的方法,但是实现中采用链表而不是栈来优化。
hopcroft法的复杂度,他们说是nlogn,可是都没有严格的证明.难得找到一篇讲的详细点的论文,却又啰里啰唆的,不过那篇论文里面采用的是颜色树这个结构,有点意思. 前面的那个算法是n的平方复杂度, ...
- 怒刷DP之 HDU 1087
Super Jumping! Jumping! Jumping! Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64 ...