SpringIoc 和 工厂模式(反射实现)
一、先演示 “简单工厂”:
package org; interface Fruit {
public void eat();
} class Apple implements Fruit {
public void eat() {
System.out.println("吃苹果。");
}
} class Orange implements Fruit {
public void eat() {
System.out.println("吃橘子");
}
} class Factory { // 工厂类
public static Fruit getInstance(String className) {
Fruit f = null;
if (className.equals("apple")) {
f = new Apple();
}
if (className.endsWith("orange")) {
f = new Orange();
}
return f;
}
} public class FactoryDemo {
public static void main(String args[]) {
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
问题:若增加新水果,如香蕉,则工厂类也要修改.
解决:java的反射机制.
二、修改“工厂类”:
//工厂类(修改)
class Factory {
public static Fruit getInstance(String className) {
Fruit f = null;
try {
f = (Fruit) Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return f;
}
}
问题:创建实例时,需要提供“完整的类名”
public class FactoryDemo2 {
public static void main(String args[]) {
Fruit f = Factory.getInstance("org.Orange");
f.eat();
}
}
解决:增加“配置文件”优化.
三、增加“配置文件”:
class PropertiesOperate{
private Properties pro=null;
private File file=new File("d:"+File.separator+"fruit.properties"); public PropertiesOperate(){
pro=new Properties();
if(file.exists()){
try {
pro.loadFromXML(new FileInputStream(file));
} catch (Exception e) {
e.printStackTrace();
}
}else{
this.save();
}
}
private void save(){
pro.setProperty("apple","org.Apple");
pro.setProperty("orange", "org.Orange");
try {
pro.storeToXML(new FileOutputStream(this.file),"Fruit");
} catch (Exception e) {
e.printStackTrace();
}
}
public Properties getProperties(){
return pro;
}
}
public class FactoryDemo3 {
public static void main(String args[]) {
Properties pro=new PropertiesOperate().getProperties();
Fruit f= Factory.getInstance(pro.getProperty("orange"));
f.eat();
}
}
通过配置文件,可以控制程序的执行,现在看起来有点像spring的ioc了。
该程序使用了工厂模式,把所有的类放在一个Factory里面,而为了动态的管理这些类(即使增加了新的Fruit类,这个工厂也不用变化),就用了java的反射机制。
另外,通过配置文件,使得一长串完整的类名称(如org.Apple)可用任意简短的名称来代替(如apple)。
四、简单的spring配置文件测试
package test; public class Person {
private String name;
private int age;
private Grade grade; public String getName() {
return name;
} public Grade getGrade() {
return grade;
} public void setGrade(Grade grade) {
this.grade = grade;
} public void setName(String name) {
this.name = name;
} public void setAge(int age) {
this.age = age;
} public int getAge() {
return age;
} public int getTotleGrade() {
return grade.getEnglish() + grade.getMath();
}
}
package test; public class Grade {
private int math;
private int english; public int getMath() {
return math;
} public void setMath(int math) {
this.math = math;
} public int getEnglish() {
return english;
} public void setEnglish(int english) {
this.english = english;
}
}
bean .xml 类
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="Person" class="test.Person"><!-- 第一个bean,是一个Person类,id名字随便取,还要写上类的全名 -->
<property name="name">
<value>小龙</value><!-- 这里的名字是通过程序里面的set来赋值的,如果去掉程序对应的set,就出错了 -->
</property>
<property name="age">
<value>23</value>
</property>
<property name="grade"><!-- 这里有点特别,这个grade变量是一个对象,和一般的变量要区别对待 -->
<ref local="Grade"/><!-- 这里指向了本配置文件里面一个名字叫Grade(即id=Grade)的bean -->
</property>
</bean>
<bean id="Grade" class="test.Grade"><!-- 同上 -->
<property name="math">
<value>99</value>
</property>
<property name="english">
<value>59</value>
</property>
</bean>
</beans>
测试类
package test; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; public class Test {
public static void main(String args[]){
Resource input = new ClassPathResource("test/Bean.xml");//Bean.xml的路径 System.out.println("resource is:" + input); BeanFactory factory = new XmlBeanFactory(input);//把input扔到工厂里面去,这个工厂就能为你提供实例了(我也不知道能不能这样说) Person person =(Person) factory.getBean("Person");//你要一个叫Person的东西,那好,工厂就去找“Person"给你
Grade grade=(Grade)factory.getBean("Grade");
System.out.println("姓名:"+person.getName());//person可以调用里面相关的方法,就相当于new了一个Person一样
System.out.println("年龄:"+person.getAge());
System.out.println("数学成绩:"+grade.getMath());
System.out.println("英语成绩:"+grade.getEnglish());
System.out.println("数学,英语总成绩:"+person.getTotleGrade());
}
}
对比前面的那个“Fruit程序”,你会发现,spring配置文件,还是一个工厂(只是换种形式一样),它管理所有的类,新建的类要到工厂里面去登记,不然就不能被主程序用,这就是为什么说ioc就是工厂模式的升级版。
SpringIoc 和 工厂模式(反射实现)的更多相关文章
- 使用传统的三层架构出现的问题.引入Spring底层实现原理来解决(工厂模式+反射+XML配置文件/注解)
以前写的代码 mapper层 public interface PersonMapper { void selectPersonList(); } public class PersonMapperI ...
- 【调侃】IOC前世今生 工厂模式 反射 依赖倒置
http://www.cnblogs.com/showjan/p/3950989.html
- C#回顾 - 7.如何使用反射实现工厂模式?
工厂模式是一种比较常用的设计模式,其基本思想在于使用不同的工厂类型来打造不同产品的部件.例如,我们在打造一间屋子时,可能需要窗户.屋顶.门.房梁.柱子等零部件.有的屋子需要很多根柱子,而有的屋子又不需 ...
- java 反射的应用 以及通过反射 用到的工厂模式
java反射详解 本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案 ...
- java反射机制(工厂模式)
http://www.phpddt.com/dhtml/338.html java里面没有typeof,js有. 我终于实现了用反射机制编写的工厂模式.java反射在工厂模式可以体现. 包含产品接口类 ...
- java 设计模式之工厂模式与反射的结合
工厂模式: /** * @author Rollen-Holt 设计模式之 工厂模式 */ interface fruit{ public abstract void eat(); } ...
- (转)java反射机制及简单工厂模式
第一步,定义一个接口类 package factory.face; /** * 接口,为了保证返回的对象可以统一用 Product接受 * @author Administrator */ publi ...
- [Java反射机制]用反射改进简单工厂模式设计
如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...
- Java反射+简单工厂模式总结
除了 new 之外的创建对象的方法 通过 new 创建对象,会使得程序面向实现编程,先举个例子,某个果园里现在有两种水果,一种是苹果,一种是香蕉,有客户想采摘园子里的水果,要求用get()方法表示即可 ...
随机推荐
- # 20145118 《Java程序设计》第4周学习总结 ## 教材学习内容总结
20145118 <Java程序设计>第4周学习总结 教材学习内容总结 本周内容为教材第六.七两张内容. 重点概念: 1.面向对象中,子类继承父类,避免重复的行为定义,是一种简化操作. 2 ...
- pip安装tensorflow-gpu好慢怎么办
答:为pip换源,如换成清华源 cat ~/.pip/pip.conf(没有此文件,自行创建即可,然后加入以下内容) [global]index-url = https://pypi.tuna.tsi ...
- CodeForces - 55D Beautiful numbers(数位DP+Hash)题解
题意:美丽数定义:一个正数能被所有位数整除.求给出一个范围,回答这个范围内的美丽数. 思路:一个数能被所有位数整除,换句话说就是一个数能整除所有位数的LCM,所以问题就转化为一个数能否被所有位数的LC ...
- 利用Html.css OPPO手机导航菜单的制作解析
<body> <div id="top" class="auto"> <div class="nav"> ...
- HTML 入门1
HTML 入门1 一,什么是HTML 超文本标记语言 二,如何写一个HTML文件? 1 通过sublime的文件->新建->保存 "文件名.html"格式 2,在 ...
- 2016"百度之星" - 初赛(Astar Round2A) 1006 Gym Class 拓扑排序
Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem ...
- python 作用域,命名空间
def scope_test(): def do_local(): spam = "local spam" def do_nonlocal(): nonlocal spam spa ...
- jquery和dom对象相互转化的方法
jQuery对象转成DOM对象: 两种转换方式将一个jQuery对象转换成DOM对象:[index]和.get(index); (1)jQuery对象是一个数据对象,可以通过[index]的方法,来得 ...
- 快速切题 poj 2993 Emag eht htiw Em Pleh 模拟 难度:0
Emag eht htiw Em Pleh Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 2806 Accepted: ...
- CentOS下Docker的安装及国内镜像配置
系统,CentOS 7,最小化安装. 升级包 >$ sudo yum upgrade 安装Docker >$ sudo yum install docker 下面开始配置国内镜像.国外的实 ...