从基础知识到重写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 模块添加的常量 ...
随机推荐
- Hadoop从2.2.0到2.7
Hadoop2.2.0 GA release 通用版本,Hadoop2.2.0就是一个通用版本 Hadoop2.2.0是从Hadoop1.1.0升级过来的,增加了以下特性: 1.增加了YARN: 2. ...
- C# 数据的加密解密
/// <summary> /// 加密数据 /// </summary> /// <param name="Text"></param& ...
- 1.4.2 solr字段类型--(1.4.2.7)字段属性使用案例
1.4.2 solr字段类型 (1.4.2.1) 字段类型定义和字段类型属性. (1.4.2.2) solr附带的字段类型 (1.4.2.3) 使用货币和汇率 (1.4.2.4) 使用Dates(日期 ...
- Eclipse中配置Tomcat碰到Server Tomcat v6.0 Server at localhost failed to start问题
控制台打印异常如下: Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/juli/logg ...
- 【Mood-3】心声
每天醒来,我都会想明白一件事情,时间是不会停下来的,如果打算活下去的话,那么我们会有25岁,会有30岁,更会有40岁,为了不让时间风干我的理想,未来只剩下抱怨,那么为明天伏笔,今天只有努力.耸耸背上行 ...
- UITableView 的增删改 自定义UITableViewCell
1.UITableView的增删改 //设置编辑模式 [self.tableView setEditing:YES animated:YES]; //可以不写 - (BOOL)tableView:(U ...
- iOS - UI - UIScrollView
1.UIScrollView 滚动视图 // 滚动视图 UIScrollView* scrollView = [[UIScrollView alloc]initWithFrame:self.view. ...
- Shell学习笔记 - 正则表达式
一.正则表达式是什么? 正则表达式是用于描述字符排列和匹配模式的一种语法规则.它主要用于字符串的模式分割.匹配.查找及替换操作. 二.正则表达式与通配符 1. 正则表达式 用来在文件中匹配符合条件的字 ...
- poj 1695 动态规划
思路:和黑书上的跳舞机类似 #include<map> #include<set> #include<cmath> #include<queue> #i ...
- python学习好书推荐
1. 编程小白的第一本 Python 入门书 http://www.ituring.com.cn/book/1863 点评:知识体系全面,作者也是功底深厚.对全面了解python非常有帮助.入门级推 ...