spring IOC

Posted zhouyeqin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring IOC相关的知识,希望对你有一定的参考价值。

本节要点:

  • IOC容器概述
  • IOC容器的工作原理
  • BeanFactory接口及常用实现类XmlBeanFactory
  • ApplicationContext接口及常用实现类
  • BeanFactory和ApplicationContext的区别

1  IOC容器概述

Spring的IoC容器实现了控制反转,即在开发过程中,开发人员不需要关心容器是怎样的,也不需要调用容器的任何API。容器会自动进行被管理对象的初始化及对象之间依赖关系的维护。

在Spring中,最重要的是两个包,提供了IoC容器的基本功能

  • org.springframework.beans
  • org.springframework.context

2         IOC容器的工作原理

org.springframework.beans.factory.BeanFactory 是Spring 容器(也叫Spring
IoC 容器)的实际代表者,BeanFactory 是IoC 容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。整个IoC 容器就是一个大的工厂,为应用程序提供bean。

 

从上图可以看到,我们可以在Spring IoC 容器中配置应用程序中所需要的信息,如POJO 对象,这些对象(Bean)之间相互依赖关系,最终产出以备使用的对象。

3         BeanFactory接口及常用实现类XmlBeanFactory

BeanFactory接口提供了多个实现类来供开发人员使用,最常使用的是org.springframework.beans.factory.xml.XmlBeanFactory类,是通过XML格式的文件来配置Bean对象以维护对象之间的关系。

使用XML格式的配置文件时,配置文件的最顶层是<beans>元素,其内部包含一个或多个<bean/>元素,其中每一个<bean/>元素定义了一个bean的实例化信息以及与其他bean之间的关系 。

BeanFactory接口中的几个基本方法:

  • Boolean containsBean(String name)

              判断Spring容器是否包含id为name的Bean实例

  • Class getType(String name)

              返回容器中指定Bean实例的类型

  • Object getBean(String name)

返回以给定名字注册的bean实例。根据bean的配置情况,如果为singleton模式将返回一个共享的实例,否则将返回一个新建的实例。如果没有找到指定的bean,该方法可能会抛出BeansException异常(实际上将抛出NoSuchBeanDefinitionException异常),在对bean进行实例化和预处理时也可能抛出异常

注:在实际的Web应用开发中,不需开发人员自己进行容器的初始化,生成BeanFactory对象,只需在web.xml文件中进行简单配置既可。

4         ApplicationContext接口及常用实现类

大部分时候,我们都不会使用BeanFactory实例作为Spring容器,而是使用ApplicationContext实例作为容器,该容器被称为Spring上下文。ApplicationContext是BeanFactory子接口,它增强了BeanFactory的功能。

ApplicationContext 接口常用的实现类:

  • ClassPathXmlApplicationContext:从类路径中的XML文件载入上下文定义信息,把上下文定义文件当成类路径文件,例:
    ApplicationContext  context=new ClassPathXmlApplicationContext(“beans- config.xml”);
  • FileSystemXmlApplicationContext:从文件系统中的XML文件载入上下文信息,例:
    ApplicationContext  context=new             FileSystemXmlApplicationContext(“d:/sp/beans-config.xml”);
    区别: FileSystemXmlApplicationContext只能在指定的路径寻找文件beans-config.xml; ClassPathXmlApplicationContext可在整个类路径中寻找。
  • XmlWebApplicationContext:从web系统中的XML文件载入载入上下文定义信息

5         BeanFactory和ApplicationContext的区别

ApplicationContext与BeanFactory都是Spring容器,职责都有实例化、定位、配置应用程序中的对象及建立这些对象间的依赖,但ApplicationContext提供更多功能:

  • ApplicationContext继承MessageResource接口,因此提供国际化支持。
  • 资源访问,比如URL和文件。
  • 事件机制,可向注册为监听器的Bean发送事件。
  • 载入多个配置文件。
  • 以声明式的方式启动、并创建Spring容器。

6          Ioc具体实现

UserDao.java

public interface UserDao {
    public void getUser();
}

UserDaomysqlImpl

public class UserDaoMySqlImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("获取mysql数据");
    }
}

 

UserDaoOracleImpl

public class UserDaoOracleImpl implements UserDao{
    @Override
    public void getUser() {
        System.out.println("获取oracle数据");
    }
}

 UserService

public interface UserService {
 public void getUser();
}

 UserServiceImpl

public class UserServiceImpl implements UserService{
    private UserDao userDao ;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void getUser() {
        userDao.getUser();
    }
}

 Beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- bean就是java对象,由spring容器创建和管理 -->
    <bean name="mysqlDao" class="com.inspur.dao.impl.UserDaoMySqlImpl"/>
    <bean name="oracleDao" class="com.inspur.dao.impl.UserDaoOracleImpl" />
    <bean id="userService" name="userService" class="com.inspur.service.impl.UserServiceImpl" >
        <!-- ref引用对象(对象由spring来创建) -->
        <property name="userDao" ref="mysqlDao"></property>
    </bean>
</beans>

test

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService us = (UserService)context.getBean("userService");
        us.getUser();
    }
}

 

7  配置文件详解
alias[ˈeliəs] 设置别名

Bean的配置

<!-- id是bean的标识符 要唯一 如果没有配置id,name默认为标识符
        如果配置id,又配置了name 那么name是别名
        name可以设置多个别名 分隔符可以是空格 逗号 分号
        class是bean的全类名=包名+类名
     -->
    <bean id="userService" name="userService" class="com.inspur.service.impl.UserServiceImpl" >
        <!-- ref引用对象(对象由spring来创建) -->
        <property name="userDao" ref="mysqlDao"></property>
    </bean>

  Import用来导入其他配置文件,实现团队协作

  <import resource="entity.xml"/>

8  Ioc两种创建对象的方式(了解)

8.1通过无参的构造方法

User.java

public class User {
    public User() {
        System.out.println("user的无参构造方法");;
    }
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    public void show(){
        System.out.println("name="+name);
    }
}

 Beans.xml

    <bean id="user" class="com.inspur.pojo.User">
        <property name="name" value="zhangsan"></property>
    </bean>

 8.2 通过有参构造方法来创建

User.java

public class User {
    public User(String name) {
        super();
        this.name = name;
        System.out.println("user的有参构造方法");
    }
    private String name;
    public void show(){
        System.out.println("name="+name);
    }
}

 Beans.xml配置

第一种   根据参数的下标来设置

<bean id="user1" class="com.inspur.pojo.User">
    <!-- index指构造方法参数下标从0开始 -->
    <constructor-arg index="0" value="lisi"></constructor-arg>
</bean>

 第二种   根据参数名称来设置

<bean id="user1" class="com.inspur.pojo.User">
        <!-- name指参数名 -->
        <constructor-arg name="name" value="lisi"></constructor-arg>
    </bean>

 第三种   根据参数类型来设置

<bean id="user1" class="com.inspur.pojo.User">
    <!-- type指参数的类型 -->
    <constructor-arg type="java.lang.String" value="lisi"></constructor-arg>
</bean>

 

以上是关于spring IOC的主要内容,如果未能解决你的问题,请参考以下文章

Spring之IOC原理及代码详解

Spring IOC源代码具体解释之整体结构

Spring 框架学习——IOC思想原型及实质

Spring IOC源代码具体解释之容器依赖注入

[Spring 源解系列] 重温 IOC 设计理念

Spring IoC