Spring----基于简单工厂模式与反射实现IOC

海浪的品格,就是无数次被礁石击碎又无数闪地扑向礁石
点赞再看 养成好习惯

想要了解IOC实现原理 就要了解反射机制以及工厂模式

什么是反射机制:


在Java运行过程中,如果我们想动态的获取到类中成员变量,函数,构造方法,那我们就要用到反射。反射可以获取到任何一个类的所有属性和方法,对于对象可以使用对象的任意方法和属性

官方对反射给出的介绍是:

反射是Java语言的一个特性,它允许程序 在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。例如它允许一个Java类获取它所有的成员变量和方法并且显示出来

利用反射我们可以创建出更加优美且多样化的代码,但是需要注意的是必须要知道用于反射的类名

反射机制的用途


  1. 在运行的时候判断对象所属的类
  2. 需要调用系统私有的方法或函数
  3. 在运行的时创建类对象
  4. 在运行时获取对象的属性,方法

为什么要使用反射


在Java编译类型中有两种:

1.静态编译:在编译时确认类型,绑定对象即通过
2.动态编译:在运行时确认类型,提升了代码的灵活程度同时也降低了代码的耦合性,体现了Java的多态,而反射就是动态编译的代表

反射相关类


实现Java反射机制的类都位于java.lang.reflect包中:

类名 用途
Class类 代表类的实体,在Java的运行过程中表示类和接口
Field类 代表类的成员变量(成员变量也被称作类的属性)
Method类 代表类的方法
Constructor类 代表类的构造方法

反射工厂和IOC


在Spring中的IOC就是工厂模式加上反射机制,我们先看一下不用反射机制时的工厂模式
interface fruit{
    public abstract void eat();
} 
class Apple implements fruit{
     public void eat(){
         System.out.println("Apple");
     }
} 
class Orange implements fruit{
     public void eat(){
         System.out.println("Orange");
     }
}
//构造工厂类
//也就是说以后如果我们在添加其他的实例的时候
//只需要修改工厂类就行了
class Factory{
     public static fruit getInstance(String fruitName){
         fruit f=null;
         if("Apple".equals(fruitName)){
             f=new Apple();
         }
         if("Orange".equals(fruitName)){
             f=new Orange();
         }
         return f;
     }
}
class hello{
     public static void main(String[] a){
         fruit f=Factory.getInstance("Orange");
         f.eat();
     }
}

缺点在于如果我们每添加一次子类,就需要修改一次工厂类,如果子类过多,工厂类会十分繁杂,不利于维护,接下来时使用反射的工厂类:

interface fruit{
     public abstract void eat();
}
class Apple implements fruit{
public void eat(){
         System.out.println("Apple");
     }
}
class Orange implements fruit{
public void eat(){
        System.out.println("Orange");
    }
}
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 hello{
    public static void main(String[] a){
        fruit f=Factory.getInstance("Reflect.Apple");
        if(f!=null){
            f.eat();
        }
    }
}

现在我们通过反射生成对象,再也不需要修改工厂类里面的代码了,在编写过程中我们只需要传入对应的类路径,反射会帮我们生成对象,下面我们做一些优化把配置改为properties里面

我们首先需要创建一个fruit.properties,里面写入对应的类路径

apple=Reflect.Apple
orange=Reflect.Orange

下面是工厂类结合反射模拟实现Spring的IOC代码:

interface fruit{
    public abstract void eat();
}
class Apple implements fruit{
    public void eat(){
        System.out.println("Apple");
    }
}
class Orange implements fruit{
    public void eat(){
        System.out.println("Orange");
    }
}
//操作属性文件类
class init{
    public static Properties getPro() throws Exception{
        Properties pro=new Properties();
        File f=new File("fruit.properties");
        if(f.exists()){
            pro.load(new FileInputStream(f));
        }else{
            pro.setProperty("apple", "Reflect.Apple");
            pro.setProperty("orange", "Reflect.Orange");
            pro.store(new FileOutputStream(f), "FRUIT CLASS");
        }
        return pro;
    }
}
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 hello{
    public static void main(String[] a) throws Exception{
        Properties pro=init.getPro();
        fruit f=Factory.getInstance(pro.getProperty("apple"));
        if(f!=null){
            f.eat();
        }
    }
}
结果为:Apple

IOC中最基本的技术就是“反射(Reflection)”编程,通俗来讲就是根据给出的类名(字符串方式)来动态地生成对象,这种编程方式可以让对象在生成时才被决定到底是哪一种对象。只是在Spring中要生产的对象都在配置文件中给出定义,目的就是提高灵活性和可维护性。

把IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言提供的反射机制,根据配置文件中给出的类名生成相应的对象

你可能感兴趣的:(java,springboot,spring)