java反射机制+工厂模式+配置文件----->在谈到spring配置文件

源文地址:http://blog.csdn.net/wangxiaolongbob/article/details/6684672

最近看了下java的反射,觉得这个讲得不错就转过来。
下面的程序是从魔乐科技java教程里面抄来的,感觉这几段程序说明了一些问题,所以就抄过来了。
下面是一个简单的工厂模式
[java] view plain copy print ?
  1. package org;
  2. interface Fruit{
  3. public void eat();
  4. }
  5. class Apple implements Fruit{
  6. public void eat(){
  7. System.out.println("吃苹果。");
  8. }
  9. }
  10. class Orange implements Fruit{
  11. public void eat(){
  12. System.out.println("吃橘子");
  13. }
  14. }
  15. class Factory{ //工厂类
  16. public static Fruit getInstance(String className){
  17. Fruit f=null;
  18. if(className.equals("apple")){
  19. f=new Apple();
  20. }
  21. if(className.endsWith("orange")){
  22. f=new Orange();
  23. }
  24. return f;
  25. }
  26. }
  27. public class FactoryDemo02 {
  28. public static void main(String args[]){
  29. Fruit f=Factory.getInstance("apple");
  30. f.eat();
  31. }
  32. }
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 FactoryDemo02 {
    public static void main(String args[]){
    Fruit f=Factory.getInstance("apple");
    f.eat();
    }
}


但是工厂类如果这样写的话,就有一个问题,如果增加了水果,比如香蕉,那么在工厂类里面也要进行相关的修改了,这样不合理,而java的反射机制可以解决这个问题
[html] view plain copy print ?
 
  
[java] view plain copy print ?
  1. package org1;
  2. interface Fruit {
  3. public void eat();
  4. }
  5. class Apple implements Fruit {
  6. public void eat() {
  7. System.out.println("吃苹果。");
  8. }
  9. }
  10. class Orange implements Fruit {
  11. public void eat() {
  12. System.out.println("吃橘子");
  13. }
  14. }
  15. class Factory {
  16. public static Fruit getInstance(String className) {
  17. Fruit f = null;
  18. try {
  19. f = (Fruit) Class.forName(className).newInstance();
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }
  23. return f;
  24. }
  25. }
  26. public class CopyOfFactoryDemo03 {
  27. public static void main(String args[]) {
  28. Fruit f = Factory.getInstance("org1.Apple");
  29. f.eat();
  30. }
  31. }
package org1;
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;
		try {
			f = (Fruit) Class.forName(className).newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return f;
	}
}
public class CopyOfFactoryDemo03 {
	public static void main(String args[]) {
		Fruit f = Factory.getInstance("org1.Apple");
		f.eat();
	}
}


利用java的反射机制,就能动态的实例化各种类了。 但是这个程序还是存在一个问题,就是主函数这里需要填入一个完整的类名称,不够方便,所以要增加配置文件来简化
[java] view plain copy print ?
  1. package org3;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.util.Properties;
  6. interface Fruit {
  7. public void eat();
  8. }
  9. class Apple implements Fruit {
  10. public void eat() {
  11. System.out.println("吃苹果。");
  12. }
  13. }
  14. class Orange implements Fruit {
  15. public void eat() {
  16. System.out.println("吃橘子");
  17. }
  18. }
  19. class Factory {
  20. public static Fruit getInstance(String className) {
  21. Fruit f = null;
  22. try {
  23. f = (Fruit) Class.forName(className).newInstance();
  24. } catch (Exception e) {
  25. e.printStackTrace();
  26. }
  27. return f;
  28. }
  29. }
  30. class PropertiesOperate{
  31. private Properties pro=null;
  32. private File file=new File("d:"+File.separator+"fruit.properties");
  33. public PropertiesOperate(){
  34. this.pro=new Properties();
  35. if(file.exists()){
  36. try {
  37. pro.loadFromXML(new FileInputStream(file));
  38. } catch (Exception e) {
  39. e.printStackTrace();
  40. }
  41. }else{
  42. this.save();
  43. }
  44. }
  45. private void save(){
  46. this.pro.setProperty("apple","org3.Apple");
  47. this.pro.setProperty("orange", "org3.Orange");
  48. try {
  49. this.pro.storeToXML(new FileOutputStream(this.file),"Fruit");
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. }
  53. }
  54. public Properties getProperties(){
  55. return this.pro;
  56. }
  57. }
  58. public class CopyOfFactoryDemo04 {
  59. public static void main(String args[]) {
  60. Properties pro=new PropertiesOperate().getProperties();
  61. Fruit f= Factory.getInstance(pro.getProperty("apple"));
  62. f.eat();
  63. }
  64. }
package org3;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;
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;
        try {
            f = (Fruit) Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return f;
    }
}
class PropertiesOperate{
    private Properties pro=null;
    private File file=new File("d:"+File.separator+"fruit.properties");
    
    public PropertiesOperate(){
        this.pro=new Properties();
        if(file.exists()){
            try {
                pro.loadFromXML(new FileInputStream(file));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else{
            this.save();
        }
    }
    private void save(){
        this.pro.setProperty("apple","org3.Apple");
        this.pro.setProperty("orange", "org3.Orange");
        try {
            this.pro.storeToXML(new FileOutputStream(this.file),"Fruit");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public Properties getProperties(){
        return this.pro;
    }
}
public class CopyOfFactoryDemo04 {
    public static void main(String args[]) {
        Properties pro=new PropertiesOperate().getProperties();
        Fruit f= Factory.getInstance(pro.getProperty("apple"));
        f.eat();
    }
}


加入配置文件问题就解决了,以后如果要增加新的水果类,都要在这个配置文件里面登记。这时我们可以说配置文件可以控制程序的执行,现在看起来有点像spring的ioc了。

其实最近在学spring 配置文件,一开始看一个好长的配置文件根本就不知道什么意思,是用来干什么的?而且看到好多的bean,百度了好多,说spring里面有ioc,还有aop(暂时还不理解aop是什么东西),可是要理解ioc就要先理解工厂模式,什么是接口,什么是java的反射。如果新手想要尽快的入门,可以尝试这个学习过程(当然我也是新手啦~~)。
下面我把我自己对spring的理解记下来:
其实我们如果理解了上面这个简单的三个程序就好办了,回顾上面的程序,该程序使用了工厂模式,把所有的类放在一个Factory里面,而为了动态的管理这些类(即使增加了新的Fruit类,这个工厂也不用变化),就用了java的反射机制。另外里面还设置了一个配置文件,使得某一长窜完整的类名称,比如org1.Apple可以用任意简短的名称来代替,比如apple。PS:如果这段话让读者感觉有点反胃,那就忘了这句废话,总之只要理解上面的程序,加上下面将要列举的小小的测试程序,我想就能理解spring配置文件的大致用途了。

简单的spring配置文件测试:
Person类
[java] view plain copy print ?
  1. package test2;
  2. public class Person {
  3. private String name;
  4. private int age;
  5. private Grade grade;
  6. public String getName() {
  7. return name;
  8. }
  9. public Grade getGrade() {
  10. return grade;
  11. }
  12. public void setGrade(Grade grade) {
  13. this.grade = grade;
  14. }
  15. public void setName(String name) {
  16. this.name = name;
  17. }
  18. public void setAge(int age) {
  19. this.age = age;
  20. }
  21. public int getAge() {
  22. return age;
  23. }
  24. public int getTotleGrade() {
  25. return grade.getEnglish()+grade.getMath();
  26. }
  27. }
package test2;
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();
	}
}

Grade类
[java] view plain copy print ?
  1. package test2;
  2. public class Grade {
  3. private int math;
  4. private int english;
  5. public int getMath() {
  6. return math;
  7. }
  8. public void setMath(int math) {
  9. this.math = math;
  10. }
  11. public int getEnglish() {
  12. return english;
  13. }
  14. public void setEnglish(int english) {
  15. this.english = english;
  16. }
  17. }
package test2;
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配置文件(该文件只要放在test2包里面就好了)(堆积木工程开始咯~~)
[html] view plain copy print ?
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
  3. "http://www.springframework.org/dtd/spring-beans.dtd">
  4. <beans>//很多豆豆
  5. <bean id="Person" class="test2.Person">//第一个豆豆,是一个Person类,id名字随便取,还要写上类的全名
  6. <property name="name">//下面开始把这个类里面的所有属性列出来,并赋值,至于你说难道一定要赋值吗?我想可以,我刚学,不知道
  7. <value>小龙</value>//这里的名字是通过程序里面的set来赋值的,不信你去掉程序里面相关的set,就出错了
  8. </property>
  9. <property name="age">
  10. <value>23</value>
  11. </property>
  12. <property name="grade">//这里有点特别,这个grade变量是一个对象,和一般的变量要区别对待
  13. <ref local="Grade"/>//这里指向了本配置文件里面一个名字叫Grade(即id=Grade)的bean
  14. </property>
  15. </bean>
  16. <bean id="Grade" class="test2.Grade">//同上
  17. <property name="math">
  18. <value>99</value>
  19. </property>
  20. <property name="english">
  21. <value>59</value>
  22. </property>
  23. </bean>
  24. </beans>
<?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="test2.Person">//第一个豆豆,是一个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="test2.Grade">//同上
		<property name="math">
			<value>99</value>
		</property>
		<property name="english">
			<value>59</value>
		</property>
	</bean>
</beans>

最后是Test测试类
[java] view plain copy print ?
  1. package test2;
  2. import org.springframework.beans.factory.BeanFactory;
  3. import org.springframework.beans.factory.xml.XmlBeanFactory;
  4. import org.springframework.core.io.ClassPathResource;
  5. import org.springframework.core.io.Resource;
  6. import test.ExampleBean;
  7. public class Test {
  8. public static void main(String args[]){
  9. Resource input = new ClassPathResource("test2/Bean.xml");//Bean.xml的路径
  10. System.out.println("resource is:" + input);
  11. BeanFactory factory = new XmlBeanFactory(input);//把input扔到工厂里面去,这个工厂就能为你提供实例了(我也不知道能不能这样说)
  12. Person person =(Person) factory.getBean("Person");//你要一个叫Person的东西,那好,工厂就去找“Person"给你
  13. Grade grade=(Grade)factory.getBean("Grade");
  14. System.out.println("姓名:"+person.getName());//person可以调用里面相关的方法,就相当于new了一个Person一样
  15. System.out.println("年龄:"+person.getAge());
  16. System.out.println("数学成绩:"+grade.getMath());
  17. System.out.println("英语成绩:"+grade.getEnglish());
  18. System.out.println("数学,英语总成绩:"+person.getTotleGrade());
  19. }
  20. }
package test2;
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;
import test.ExampleBean;
public class Test {
	public static void main(String args[]){
		Resource input = new ClassPathResource("test2/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());
	}
}

如此看来,你在对比一开始的那个水果的程序,你会发现,spring配置文件,还是一个工厂,只不过换种形式一样,他管理所有的类,新建的类要到工厂里面去登记,不然就不能被主程序用,这就是为什么说ioc就是工厂模式的升级版。至于配置文件的书写,就跟堆积木一样,当然我现在学的还是表面东西。

你可能感兴趣的:(java,工厂模式,配置文件,反射机制)