Spring-(2)Spring IOC

Spring-(2)Spring IOC

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

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

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


这是Spring官方文档上对Spring IOC容器的描述
这里写图片描述
这个意思是将Java的POJO类注入到Spring的IOC容器中,然后容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序,如果我们需要一个对象,我们只需要告诉IOC容器,然后IOC容器就会帮我new一个对象,这就是IOC容器的作用。

Spring 提供了以下两种不同类型的容器

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

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

    需要说明的是,ApplicationContext 的功能比BeanFactory 更多,它包含了BeanFactory ,所以一般我们做大型来说,用ApplicationContext 更好。但BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。

Spring BeanFactory容器

这是一个最简单的容器,它主要的功能是为依赖注入 (DI) 提供支持,这个容器接口在 org.springframework.beans.factory.BeanFactor 中被定义。 BeanFactory 和相关的接口,比如,BeanFactoryAware、 DisposableBean、InitializingBean,仍旧保留在 Spring 中,主要目的是向后兼容已经存在的和那些 Spring 整合在一起的第三方框架。

在 Spring 中,有大量对 BeanFactory 接口的实现。其中,最常被使用的是 XmlBeanFactory 类。这个容器从一个 XML 文件中读取配置元数据,由这些元数据来生成一个被配置化的系统或者应用。

在资源宝贵的移动设备或者基于 applet 的应用当中, BeanFactory 会被优先选择。否则,一般使用的是 ApplicationContext,除非你有更好的理由选择 BeanFactory。

我们来看一个例子:
这里写图片描述
HelloSpring是一个POJO类(直接贴源代码)

public class HelloSpring {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

}

Bean.xml(关于基本的配置我已经在Spring-(1)HelloSpring中讲到了,废话不多说,直接贴代码)

<?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-4.3.xsd">
        <bean id="springBeanFactory" class="com.tbspringIOC.BeanFactory.HelloSpring">
        <property name="message" value="Hello Spring BeanFactory !"></property>
    </bean>
</beans>

最后再把测试的Main贴上来(呐,注释我都写好了,我真是尽心尽力!)
PS:getBean方法里面的参数是xml文件里面bean 的id值

public class MainAPP {

    public static void main(String[] args) {
        //利用框架提供的 XmlBeanFactory() API 去生成工厂 bean 以及利用 ClassPathResource() API 去加载在路径 CLASSPATH 下可用的 bean 配置文件
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("Beans.xml"));
        //用beanFactory的getBean方法也可以获得bean对象(一般都用ApplicationContext,ApplicationContext比BeanFactory功能更全)
        //BeanFactory 仍然可以在轻量级应用中使用,比如移动设备或者基于 applet 的应用程序。
        HelloSpring hSpring = (HelloSpring) beanFactory.getBean("springBeanFactory");
        System.out.println(hSpring.getMessage());
    }

}

然后打印结果成功!
这里写图片描述
Spring BeanFactory容器到这里就差不多结束了!


Spring ApplicationContext 容器

Spring ApplicationContext 容器也很简单,我们在 Spring-(1)HelloSpring 的例子中用的就是ApplicationContext。(节约时间,废话不多说,直接贴代码(其实是自己懒不想打字!))
这里写图片描述
看一下目录结构,HelloSpring类,Beans.xml与上面用到的例子是一样的,我们直接看一下Main中不一样的部分。

public class MainAPP {

    public static void main(String[] args) {
        //我们把BeanFactory改成了ApplicationContext
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        HelloSpring hSpring = (HelloSpring) context.getBean("springApplicationContext");
        System.out.println(hSpring.getMessage());
    }

}

这就是Spring ApplicationContext 容器


现在来看一下Bean的用法

我们在上面的例子中已经接触了bean中的id和class,但是bean还要其他几个属性。

属性描述
class这个属性是强制性的,并且指定用来创建 bean 的 bean 类
name这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 或 name 属性来指定 bean 标识符(我一般用id)
scope这个属性指定由特定的 bean 定义创建的对象的作用域
constructor-arg它是用来注入依赖关系的(构造器注入)
properties它是用来注入依赖关系的(setter注入)
autowiring mode它是用来注入依赖关系的(自动注入)
lazy-initialization mode延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例
initialization 方法在 bean 的所有必需的属性被容器设置之后,调用回调方法
destruction 方法当包含该 bean 的容器被销毁时,使用回调方法

看表可能比较难懂,可以看一下伪代码:

<bean id="指定上下文唯一标识" class="类的全限定名称"
  lazy-init="懒加载(默认为false,懒加载的意思是等到对象创建时才进行加载,而不是在容器初始化时进行加载)"
   init-method="调用类中的一个初始化方法(只需要写方法名)"
    destroy-method="调用类中的一个销毁方法(只需要写方法名)"
     parent="父对象ID(这个相当于Java里面的继承关系)" >
    <!-- scope="默认为singleton(单例),我们可以手动修改为prototype" 添加范围后不能执行销毁方法 -->

        <property name="类中的属性或方法名" value="赋值"></property>
    </bean>

这大概就是IOC的基本概念和用法了,如写得不对,望指出,谢谢!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值