从基础知识到重写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 模块添加的常量 ...
随机推荐
- win7+iss7的配置,以及如何在本地IIS服务器挂载一个网站
虽然学过在XP安装IIs服务器和在IIS服务器挂载网站的东西,但是win7和XP的方式还是有许多不同的.废话不说直接进入正题 在本地安装IIS服务器 在IIS服务器中添加你的项目 将你项目的首页设置为 ...
- 进程控制之exec函数
用fork函数创建子进程后,子进程往往要调用一种exec函数以执行另一个程序.当进程调用一种exec函数时,该进程执行的程序完全替换为新程序,而新程序则从其main函数开始执行.因为调用exec并不创 ...
- Linux 混杂设备、外部中断和输入子系统
混杂设备也是一种字符设备,主设备号固定为10.相对于普通字符设备驱动,它不需要自己去生成设备文件. 1.声明使用的头文件 #include <linux/miscdevice.h> 2.定 ...
- JAVA WEB 作用域之间的区别
JAVA WEB 作用域 1.page属性范围(pageContext) a.在一个页面设置的属性,跳转到其他页面就无法访问了(包括重定向和). 示例:pageScopeDemo01.jsp < ...
- IOS开发之--异常处理--使用try 和 catch 来捕获错误。
一个搞java的老板问我会不会try catch 我说不会 学这么久也没听周围朋友用这个 因为苹果控制台本来就可以打印异常 特此研究一下. 1.try catch: 是捕获异常代码段 特点:对 ...
- [Arduino] Arduino Uno R3 中文介绍
Arduino UNO是Arduino USB接口系列的最新版本,作为Arduino平台的参考标准模板.UNO的处理器核心是ATmega328,同时具有14路数字输入/输出口(其中6路可作为PWM输出 ...
- iOS部分其他知识
1.界面切换传值 (1)使用button进行界面切换 //当页面跳转时系统自动调用,segue连线 - (void)prepareForSegue:(UIStoryboardSegue *)segue ...
- [Android]天气App 3 网络数据的请求和Json解析
Android客户端开发,不仅仅是在Android端开发,还需要有相应的后台服务支持,否则的话,客户端的数据就只能放到本地自己做处理.我认为的原生态的App就是对应服务端的Client.他能像浏览 ...
- js的时间操作方法
1.js获取系统时间格式为YYYY-MM-DD HH:MM:SS 1 function curDateTime(){ 2 var d = new Date(); 3 var year = d.getY ...
- Linux+Apache+Php+Oracle 基础环境搭建
前言: 不能保证100%一次通过,每个系统都会或多或少有区别,如果缺少某些依赖包的话,还请见谅 1.安装Apache需要编译安装的包,各官方网站下载 ...