`
chenguanwei2008
  • 浏览: 121114 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

手动实现IOC容器

阅读更多

IOC(Inversion of Control),即控制反转,它使你不需要再自己来实现对象的创建,而是把这些工作都交由容器来进行管理,增加了代码的可重用性。下面,便手动实现一个简单的IOC容器。

首先建立一个接口和这个接口的2个实现类:

 

package cn.cgw.ioc;
public interface ReportGenerator {
	
	public void generate(String[][] table);
}

 

package cn.cgw.ioc;
public class HtmlReportGenerator implements ReportGenerator {

	public void generate(String[][] table) {
		System.out.println("Generate HTML report...............");
	}
}

 

package cn.cgw.ioc;
public class PdfReportGenerator implements ReportGenerator {

	public void generate(String[][] table) {
		System.out.println("Generate PDF report..................");
	}
}

 

 

然后,我们建立一个名为ReportService的类,在这个类中需要到ReportGenerator接口的实现类对象,我们不再手工创建它,而是由IOC容器来管理,在这个类中采用setter方法进行注入。

package cn.cgw.ioc;

public class ReportService {

	private ReportGenerator reportGenerator;
	
	/**
	 * 采用setter注入
	 * @param reportGenerator
	 */
	public void setReportGenerator(ReportGenerator reportGenerator) {
		this.reportGenerator = reportGenerator;
	}
	
	public void generateAnnualReport(int year) {
        String[][] statistics = null;
        //
        // Gather statistics for the year ...
        //
        reportGenerator.generate(statistics);
    }

    public void generateMonthlyReport(int year, int month) {
        String[][] statistics = null;
        //
        // Gather statistics for the month ...
        //
        reportGenerator.generate(statistics);
    }

    public void generateDailyReport(int year, int month, int day) {
        String[][] statistics = null;
        //
        // Gather statistics for the day ...
        //
        reportGenerator.generate(statistics);
    }
}

 下面我们建立一个属性文件,在属性文件中,定义了属性与对应类的映射关系:

# Define a new component "reportGenerator"
reportGenerator=cn.cgw.ioc.HtmlReportGenerator

# Define a new component "reportService"
reportService=cn.cgw.ioc.ReportService
# Inject the component "reportGenerator" into property "reportGenerator"
reportService.reportGenerator=reportGenerator

 然后,我们实现IOC容器,在这个类中需要用到Apache的两个jar包。分别是common-logging和common-beanutils

package cn.cgw.ioc;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.beanutils.PropertyUtils;

public class Container {
	
	private Map<String,Object> components;

	public Container() {
		
		components = new HashMap<String,Object>();
		
		try {
			Properties properties = new Properties();
			//load properties file
			InputStream istr = this.getClass().getResourceAsStream("components.properties");
			properties.load(istr);
			
			for(Map.Entry entry : properties.entrySet()) {
				String key = (String)entry.getKey();
				String value = (String)entry.getValue();
				processEntry(key,value);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void processEntry(String key, String value) throws Exception{
		String[] parts = key.split("\\.");
		//new component definition
		if(parts.length == 1) {
			//reflection
			Object component = Class.forName(value).newInstance();
			components.put(parts[0], component);
		} else {
			// Dependency injection
			Object component = components.get(parts[0]);
			Object reference = components.get(value);
			PropertyUtils.setProperty(component,parts[1],reference);
		}	
	}
	
	public Object getComponent(String id) {
		return components.get(id);
	}
}

 这样我们的工作就完成了,最后再写个测试方法来检验代码的正确性:

Container container = new Container();
ReportService reportService = (ReportService)container.getComponent("reportService");
reportService.generateAnnualReport(2009);

 可以看到,输出的结果为:

 Generate HTML report...............

 如果,我们将属性文件中reportGenerator=的值改为PdfReportGenerator,则输出的结果为:

 Generate PDF report...............

 

通过以上结果我们可以清楚地认识到IOC的特性,我们并没有在ReportService类中创建ReportGenerator的任何实现类对象,这一切都是交由IOC容器进行管理的,通过属性文件的配置,我们可以轻松地更改想要使用的ReportGenerator实现类对象,它大大提高了代码的复用性。

分享到:
评论

相关推荐

    手动实现一个ioc容器.zip

    标题 "手动实现一个IOC容器.zip" 提到的主题是关于如何从零开始构建自己的依赖注入(Dependency Injection,简称DI)容器,这在Java开发中尤为重要,特别是对于Spring框架的理解和学习。IOC容器是Spring的核心功能之...

    Spring-IoC-Learning:手动实现IoC容器

    这个项目"Spring-IoC-Learning:手动实现IoC容器"旨在通过实践来深入理解Spring IoC的工作原理。在本文中,我们将探讨Spring IoC的基本概念、工作流程,并尝试手动实现一个简单的IoC容器。 首先,了解IoC的概念至关...

    有关IOC组件(.net core内置组件,和第三方Autofac组件)的使用,以及自己实现IOC

    手动实现IOC容器虽然相对复杂,但可以帮助理解DI的工作原理。基本步骤包括: 1. 定义服务接口和服务实现。 2. 创建一个容器类,用于存储服务和它们的实例。 3. 实现注册方法,将服务接口和服务实现关联起来。 4. ...

    模拟Spring的IoC容器实现注解自动装配

    现在,我们将深入探讨如何模拟Spring的IoC容器实现注解自动装配。 首先,我们需要理解IoC容器的基本工作原理。IoC容器是通过扫描应用程序上下文来发现所有需要管理的bean,并根据bean定义来创建和初始化这些bean。...

    IoC 容器和Dependency Injection 模式

    在 Java 社区中,有一些流行的 IoC 容器实现了依赖注入,比如 Spring Framework 和 PicoContainer。这些框架提供了一系列工具和 API 来支持 IoC 和 DI,使开发者能够更加高效地组织和管理项目中的组件。 - **Spring...

    手写一个SpringIoc容器

    在实现自定义的Spring IOC容器时,我们需要关注以下几个核心知识点: 1. **Bean的定义与注册**:首先,我们需要创建一个表示Bean的类或接口,包含Bean的ID、类名等信息。Bean的定义可以通过XML配置文件、注解或者...

    实现ioc功能的spring框架

    在 "MySpring" 这个实现中,你可能已经包含了创建 IoC 容器、解析配置(可能是 XML 或注解)、实例化和管理 Bean 的代码。这将涉及反射机制、Java 注解处理和可能的自定义加载逻辑。通过这个项目,你可以深入理解 ...

    自己搭建IOC容器(C#)

    可能涉及到.NET Framework或.NET Core的相关库,例如Microsoft.Extensions.DependencyInjection,这是一个官方提供的IOC容器,但题目要求是自定义实现,所以开发者需要理解DI的基本原理,并手动实现类似的功能。...

    Spring中IoC优点与缺点解析

    1. 简化对象的创建:IoC 容器可以自动地创建和管理对象,无需手动地创建和销毁对象,从而简化了编程的步骤。 2. 解耦合对象之间的依赖关系:IoC 容器可以将对象之间的依赖关系解耦合,使得对象之间的耦合度降低,...

    仿spring ioc 容器

    "仿spring ioc 容器"这个主题,旨在探讨如何理解和实现类似于Spring框架中的IoC容器的功能。 IoC容器是Spring的核心,它负责创建对象、管理对象间的依赖关系以及对象的生命周期。在Spring中,IoC使得开发者不再需要...

    java代码实现简易版IOC容器!.docx

    在这个简易版的Java IOC容器实现中,我们将探讨如何通过自定义注解和反射机制来构建一个基础的IoC容器。 首先,我们有两个自定义注解:`@MyComponent` 和 `@MyAutowired`。 1. `@MyComponent` 是一个类型注解,...

    IOC容器 mini-container

    在Java世界里,Spring框架是最著名的IOC容器实现之一,但除此之外,还有很多小型、轻量级的IOC容器,比如本案例中的"mini-container"。 "mini-container"是一个开源项目,它的目标是提供一个功能简洁但实用的IOC...

    自己实现ioc实例demo

    在实际开发中,IoC容器如Spring框架已经提供了强大的依赖注入功能,可以自动管理对象的生命周期和依赖关系。但理解如何手动实现这个过程可以帮助我们更好地理解IoC的核心原理,从而更有效地利用现有的IoC框架。 总...

    体验Spring的IoC容器的优点(Eclipse中).doc

    IoC 容器的主要作用是将对象的创建和管理交由容器来处理,从而实现对象之间的解耦合。IoC 容器的优点在于可以降低对象之间的耦合度,提高系统的灵活性和可维护性。 在本实验中,我们将通过使用 Eclipse IDE 来体验 ...

    spring IOC容器依赖注入XML配置

    在本教程中,我们将深入探讨如何通过XML配置在Spring IOC容器中实现依赖注入。 首先,我们需要了解Spring的IOC容器。IOC容器是Spring的核心,它负责管理对象的生命周期和对象间的依赖关系。容器通过读取XML配置文件...

    “IOC容器与DI依赖注入示例”文章提及

    `spring_01_quickstart`这个文件可能包含了一个Spring快速入门的示例,可能会涵盖如何创建Spring项目,配置IOC容器,以及实现DI的基本步骤。在实际学习过程中,你可以通过创建Spring Boot项目,定义简单的bean并进行...

    Spring容器中IOC

    IOC容器还提供了依赖注入的功能,可以将对象之间的关系维护到容器中,例如,ScheduleController需要ScheduleService1对象,程序员不需要手动创建ScheduleService1对象,而是通过容器来获取对象实例。 在使用IOC容器...

    IOC控制反转代码,bilibili配套文件

    控制反转是将对象的创建进行反转,常规情况下,对象都是开发者手动创建的,但是在 IOC 容器中,开发者设计好对象的类,将这些设计好了的类交给 IOC 容器,IOC 容器来创建并控制这些对象。 IOC 容器的主要功能是: ...

    简单记录spring 实现IOC的流程

    DI则是一种实现IOC的方式,它允许我们通过容器来注入所需的依赖,而不是在类内部硬编码这些依赖。 Spring实现IOC的过程主要包括以下几个步骤: 1. **配置解析**:Spring配置通常以XML或Java注解的形式存在。在启动...

    C#实现IOC代码,供学习用

    本篇我们将聚焦于C#实现的IOC(Inversion of Control,控制反转),即DI的一种形式,主要讲解如何自定义实现一个简单的IOC容器。 标题中提到的“C#实现IOC代码”通常指的是开发者为了理解和掌握DI原理,自己编写了...

Global site tag (gtag.js) - Google Analytics