Spring IOC原理
Spring中的IoC的实现原理就是工厂模式加反射机制。IOC机制作用:将类的创建和依赖关系写在配置文件里,由配置文件注入,实现了松耦合。简而言之,将对象创建过程的职责赋予容器,通过容器管理对象的生老病死, 将对象创建过程从编译时延期到运行时,即通过配置进行加载,这样一来就解决了不用编译后期选择具体实现,其实就是面向对象的核心理念,针对接口编程。IOC是个factory加上依赖管理,系...
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)