Spring的IOC容器为什么用反射而不用new来创建实例?

1. 什么是反射?

       反射是java的一种特性,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射的四种创建对象方式

  1. 对象.getClass()的形式获取对象

    Person person=new Student();
    Class person1 = person.getClass();
    
  2. 通过Class.forName()创建反射获取对象

    Class person2 = Class.forName("com.xuan.反射.Student");
    
  3. 通过类名.class创建反射获取对象

    Class <Student> person3 = Student.class;
    
  4. 通过类加载器获取对象

    ClassLoader cl = this.getClass.getClassLoader(); // 使用当前类的ClassLoader 
    Class clazz = cl.loadClass("com.rain.B") // 使用第一步得到的ClassLoader来载入B
    B b = (B)clazz .newInstance(); // 有B的类得到一个B的实例 
    

2. 反射与new的区别

  1. 反射和new都是创建对象实例的,但是new对象无法调用该类里面私有private的属性,而反射可以调用类中private的属性!
  2. new属于静态编译。就是在编译的时候把所有的模块都确定,如果有添加或删除某些功能,需要重新编译。但系统不可能一次就把把它设计得很完美,当发现需要更新某些功能时,采用静态编译的话,需要把整个程序重新编译一次才可以实现功能的更新。也就是说,用户需要把以前的软件卸载了,再重新安装才会重新编译!这样的系统耦合严重,难以扩展!
  3. 反射属于动态编译。在运行时确定类型并创建对象,通过反射指定模板,动态的向模板中传入要实例化的对象。动态编译最大限度发挥了Java的灵活性,体现了多态的应用,有以降低类之间的藕合性。其中springioc的核心就是利用了反射解耦合。
  4. 反射效率较低,但经过jdk很多版本的优化,效率已经很高了!

       

2. IOC为什么要使用 工厂 + 反射 创建对象?

       Spring中的IoC的实现原理就是工厂模式加反射机制。 如果工厂模式中不使用反射,而使用new创建对象:

	//接口 fruit
	interface fruit{
	    public abstract void eat();
	} 
	
	//实现类 Apple 
	class Apple implements fruit{
	     public void eat(){
	         System.out.println("Apple");
	     }
	} 
	
	//实现类 Orange 
	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();
	        }
	    }
	}

       这样使用反射的方式,无论我们创建多少fruit的实例,都不需要修改反射生成的工厂模板,有效的降低了系统耦合性!

       IOC容器的工作模式看做是工厂模式的升华,可以把IOC容器看作是一个工厂,这个工厂里要生产的对象都在配置文件中给出定义,然后利用编程语言提供的反射机制,根据配置文件中给出的类名生成相应的对象。从实现来看,IOC是把以前在工厂方法里写死的对象生成代码,改变为由配置文件来定义,也就是把工厂和对象生成这两者独立分隔开来,目的就是提高灵活性和可维护性。

  • 22
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值