Spring IoC容器

本文详细介绍了Spring框架中的IoC容器概念,包括其核心功能、依赖注入原理及其在解耦应用程序中的作用。探讨了Spring提供的两种容器类型:BeanFactory和ApplicationContext,以及它们在配置元数据和管理对象生命周期中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring IoC容器

IoC 容器

  • Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为spring Beans。
  • 通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。配置元数据可以通过 XML,Java 注释或 Java 代码来表示。
  • IOC 容器具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中BeanFactory是IOC容器的实际代表者。

spring 提供了两种不同类型的容器

  1. Spring BeanFactory容器

它是最简单的容器,给 DI 提供了基本的支持,它用
org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory
或者相关的接口,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring
中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。

  1. Spring AppicationContext容器

该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应
用程序事件给感兴趣的事件监听器的能力。该容器是由
org.springframework.context.ApplicationContext 接口定义

ApplicationContext 容器包括 BeanFactory 容器的所有功能

对IOC和DI的理解

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。 在Java开发中,**Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。**如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

●谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。

●为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

DI—Dependency Injection,即“依赖注入”组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。**依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。**通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

理解DI的关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么”,那我们来深入分析一下:

●谁依赖于谁:当然是应用程序依赖于IoC容器

●为什么需要依赖:应用程序需要IoC容器来提供对象需要的外部资源

●谁注入谁:很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象

●注入了什么:就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

IoC和DI由什么关系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。

​ IoC 不是一种技术,只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合、更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是
松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

​ 其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了“主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入,而不是由对象主动去找。

以上的内容来自http://sishuok.com/forum/blogPost/list/2427.html


​ **自己的想法:**IOC或者DI就是一设计思想的叫法,spring框架用一种容器(IOC容器)实现了这种思想,对应用程序进行解耦,灵活配置。spring框架提供了一个容器,来集中管理所有的对象资源等等,容器在应用程序需要某些资源的时候送过去,这样两个对象间的依赖就解耦了,现在就变成了两个对象都依赖于spring容器,其中一个向spring容器注册资源,另一个和spring容器要资源。

Spring BeanFactory容器(废弃)

又是一个入门的小例子,基本和HelloWorld一致

  • 建立工程
  • 将spring框架需要的jar包导入工程
  • 建立文件,Main.java,Helloworld.java,Beans.xml
  • 编辑,运行

就在前面的HelloWorld上改代码,只需要修改HelloWorld.java即可

package com.tutorialspoint;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
public class MainApp {
	public static void main(String[] arg) {

		//利用框架提供的 XmlBeanFactory() API 去生成工厂 bean ,
		// ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件
		XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("Beans.xml"));
		
		/*
		  使用已创建的factory 的 getBean() 方法来获得所需的 bean,这个方法使用 bean 的 
		  ID 返回一个最终可以转换为实际对象的通用对象
		*/
		HelloWorld obj = (HelloWorld)factory.getBean("helloWorld");
		System.out.println(obj.getMessage());
		
	}
}

这种写法已经废弃了,不推荐使用

SpringAplicationContext容器

第一个示例程序sprigHelloWorld就使用了springAplicationContext容器,这是目前的一般写法。

对于如何得到ApplicationContext有很多种写法

ApplicationContext context = new FileSystemXmlApplicationContext("src/Beans.xml");
//或者是
ApplicationContext context2 = new ClassPathXmlApplicationContext("Beans.xml");

//下面这种写法更加灵活
GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();


ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");

配置bean除了可以使用xml文件外,还可以用Groovy,来定义

beans {
    dataSource(BasicDataSource) {
        driverClassName = "org.hsqldb.jdbcDriver"
        url = "jdbc:hsqldb:mem:grailsDB"
        username = "sa"
        password = ""
        settings = [mynew:"setting"]
    }
    sessionFactory(SessionFactory) {
        dataSource = dataSource
    }
    myService(MyService) {
        nestedBean = { AnotherBean bean ->
            dataSource = dataSource
        }
    }
}
// 加载
ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");

//或者是
GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值