Spring IOC原理

Spring中的IoC的实现原理就是工厂模式加反射机制。

IOC机制

**作用:**将类的创建和依赖关系写在配置文件里,由配置文件注入,实现了松耦合。简而言之,将对象创建过程的职责赋予容器,通过容器管理对象的生老病死, 将对象创建过程从编译时延期到运行时,即通过配置进行加载,这样一来就解决了不用编译后期选择具体实现,其实就是面向对象的核心理念,针对接口编程。IOC是个factory加上依赖管理,系统的创建过程就从原先的new改为配置组装,内部通过注入解决了依赖关系,只要满足接口协议即插即用。
**定义:**控制反转(Inversion of Control)和依赖注入(Dependecy Injection)是同一个概念:当一个对象需要另外一个对象协助的时候,体现在对象的引用,比如学生对象调用生日对象,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在spring中创建被调用者的工作不再由调用者来完成,因此称为控制反转(创建对象由调用者转移到spring容器)。创建被调用者的工作由spring来完成,然后注入调用者因此也称为依赖注入。

spring以动态灵活的方式来管理对象 , 注入的两种方式,设置注入和构造注入。

  • 设置注入的优点:直观,自然
  • 构造注入的优点:可以在构造器中决定依赖关系的顺序。

实现反射机制工厂

Spring中的IoC的实现原理就是工厂模式加反射机制,那么首先看一下简单工厂模式,再看使用反射机制的工厂

工厂不用反射机制时,当添加一个子类的时候,就需要修改工厂类了。如果添加太多的子类,修改的代码就会很多。(即使工厂使用多方法或者多静态方法)
Product.java

package com.factory.demo;

public interface Product {
	public void shape();

	public void color();
}

Cup.java

package com.factory.demo;

public class Cup implements Product {

	@Override
	public void shape() {
	}

	@Override
	public void color() {
		System.out.println("cup:black!");
	}

Computer.java

package com.factory.demo;

public class Computer implements Product {

	@Override
	public void shape() {
	}

	@Override
	public void color() {
		System.out.println("computer:red");
	}

}

ProductFactory.java

package com.factory.demo;

public class ProductFactory {

	public Product getProduct(String productName) {

		Product product = null;

		if (productName.toLowerCase().equals("cup")) {
			product = new Cup();
		} else if (productName.toLowerCase().equals("computer")) {
			product = new Computer();
		}else{
			System.out.println("error");
		}
		return product;
	}
}

Main.java

package com.factory.demo;

public class Main {

	public static void main(String[] args) {
		ProductFactory productFactory= new ProductFactory();
		productFactory.getProduct("cup").color();
	}
}

现在增加产品种类,比如工厂需要生产眼镜,需要增加眼镜类和修改工厂方法
增加Glasses.java

package com.factory.demo;

public class Glasses implements Product {

	@Override
	public void shape() {
	}

	@Override
	public void color() {
		System.out.println("glasses:null");
	}
}

修改ProductFactory.java

package com.factory.demo;

public class ProductFactory {

	public Product getProduct(String productName) {

		Product product = null;

		if (productName.toLowerCase().equals("cup")) {
			product = new Cup();
		} else if (productName.toLowerCase().equals("computer")) {
			product = new Computer();
		}else if (productName.toLowerCase().equals("glasses")) {
			product = new Glasses();
		}else{
			System.out.println("error");
		}
		return product;
	}
}

就如前面描述如果增加的产品过多,代码量也会很多(工厂多方法模式和多静态方法模式代码不在此展示,不清楚的可以去参考设计模式)

使用多工厂模式:也需要增加工厂类

既然如此,继续看使用反射机制的工厂模式,代码是否比普通工厂模式精炼?

ProductFactoryByReflect.java

package com.factory.demo;

public class ProductFactoryByReflect {
	
	public static Product getProduct(String ClassName) {
		Product product = null;
		try {
			product = (Product) Class.forName(ClassName).newInstance();
		} catch (Exception exception) {
			exception.printStackTrace();
		}
		return product;
	}
}

测试:

package com.factory.demo;

public class Main {

	public static void main(String[] args) {
		ProductFactory productFactory= new ProductFactory();
		productFactory.getProduct("cup").color();
		
		ProductFactoryByReflect.getProduct("com.factory.demo.Glasses").color();
	}

}

再添加新的产品时,工厂类不需要做修改

使用反射机制的工厂模式可以通过反射取得接口的实例,但是需要传入完整的包和类名。而且用户也无法知道一个接口有多少个可以使用的子类,所以通过属性文件的形式配置所需要的子类。

IOC

使用反射机制并结合属性文件的工厂模式就是IOC的本质,不神秘~不神秘

在工程中创建配置文件cfg.properties,(使用过spring的想想xml配置文件)

cup=com.factory.demo.Cup
computer=com.factory.demo.Computer
glasses=com.factory.demo.Glasses

测试:直接使用反射机制的工厂类

package com.factory.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class IOCTest {

	public static void main(String[] args) throws FileNotFoundException, IOException {
		// TODO Auto-generated method stub
		Properties pro=getProperties();
        Product product=ProductFactoryByReflect.getProduct(pro.getProperty("glasses"));
        if(product!=null){
            product.color();
        }

	}
	public static Properties getProperties() throws FileNotFoundException, IOException{
        Properties properties=new Properties();
        File file=new File("cfg.properties");
        if(file.exists()){
            properties.load(new FileInputStream(file));
        }else{
            properties.setProperty("cup", "com.factory.demo.Cup");
            properties.setProperty("computer", "com.factory.demo.Computer");
            properties.setProperty("glasses", "com.factory.demo.Glasses");
            properties.store(new FileOutputStream(file), "");
        }
        return properties;
    }
}

输出glasses的颜色:null

glasses:null
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值