Spring 系列 | IOC及 Spring IOC 的具体表现形式

Spring 系列 | IOC及 Spring IOC 的具体表现形式,第1张

Spring 系列 | IOC及 Spring IOC 的具体表现形式

今天的主要内容是IOC ,用不太严谨但好懂的大白话来说,IOC是一种设计思想,就是把原来由应用程序自己来主动创建查找 管理对象的那部分,交给了框架处理。只要你告诉框架,你是那个对象,你需要哪个对象就可以了。不用在自己去找这个对象在哪里,也不用管怎么去找到并创建和销毁这个对象了。

IOC及 Spring IOC 的具体表现形式

IOC是什么

定义实现策略容器的职责一些开源组件的主要实现

传统IOC容器的实现 Spring IoC 容器

依赖查找示例:

1 通过Bean名称 的方式来查找2 通过类型查找3 通过注解查找 依赖注入示例

手动方式自动配置 依赖注入和查找的对象来自于哪里配置元信息Spring IOC 容器生命周期 总结
本文重点聚焦两个问题,一个是IOC 是什么,另一个是IOC在spring中是怎么体现和应用的。

思路:
IOC是什么?
在一些开源框架里 IOC 都是怎么用的?
在Spring里 IOC是怎么用的?
更具体点,则是:包含 怎么找,怎么注入,怎么配置,数据源是那些,对象的生命周期,以及谁控制的 这些信息

IOC是什么

从定义和主要实现策略两个维度来展开

定义

IOC 在维基百科上的定义是这样写的

In software engineering, inversion of control (IoC) is a programming principle.

IOC 是 inversion of control 的缩写,即控制反转。它是一种编程的原则或风格。
说起IOC的简史,它最早是1983年,Richard E.Sweet 在《TheMesaProgrammingEnvironment》中提出的 “Hollywood Principle” ,即 “好莱坞原则”,主要表达的意思也是大家很熟悉的一句话“不要来打电话给我,我会打电话给你” ,也就是导演 在会去联系演员,导演会打电话给演员,而不是演员主动联系导演。这里面其实就是控制反转的原则,在程序里对应则是:我们的依赖 或是我们的数据是由其他方来提供的,而非自己去读取的。

实现策略

在维基百科中 Inversion_of_control 有这样的定义:

In object-oriented programming, there are several basic techniques to implement inversion of control. These are:
• Using a service locator pattern (注:服务定位模式)
• Using dependency injection (注:依赖注入), for example
• Constructor injection (注:构造器注入)
• Parameter injection (注:参数注入)
• Setter injection (注:setter注入)
• Interface injection (注:接口注入)
• Using a contextualized lookup (注:上下文的依赖查询 例如 bean context )
• Using template method design pattern (注:模板方法的设计模式)
• Using strategy design pattern (注:策略模式)

容器的职责

1 实现与任务的执行 要解耦
2 关注设计上的最终目标 而不是具体实现
3 对象生命周期的管理
4 配置

一些开源组件的主要实现

接下来看看IOC 容器在一些开源组件上的主要实现

Java SE : Java Beans,Java ServiceLoader SPI ,JNDI(Java Naming and Directory Interface)Java EE :EJB(Enterprise Java Beans) Servlet其他开源
• Apache Avalon(http://avalon.apache.org/closed.html)
• PicoContainer(http://picocontainer.com/)
• Google Guice(https://github.com/google/guice)
• Spring framework(https://spring.io/projects/spring-framework)

从EJB 3.0 开始,就出现了所谓的依赖注入和依赖查找并存的情况,之前大部分都是依赖查找形式。 这也算是一个小的分水岭了

接下来针对一个具体的框架来进行特性说明
Java Beans 作为IOC 容器特性

传统IOC容器的实现

特性:

    依赖查找生命周期配置元信息事件自定义资源管理持久化

接下来重点聊下IOC 的依赖注入和依赖控制

Spring IoC 容器

IOC在spring中是怎么体现和应用的。包括 怎么进行的依赖注入或查找,包括相关的配置,以及对象的源等。
IOC 是控制反转,这里再讲Spring IOC时,仍然是结合IOC 的特性来讲,在Spring里 是如何做到的依赖查找和依赖注入,再依赖查找里 具体是通过什么形式,再依赖注入里又是通过什么形式。将结合代码来看一下。这是这篇文章我最想详细介绍的内容

依次展示几个依赖查找和注入的案例:

依赖查找示例: 1 通过Bean名称 的方式来查找

如:beanFactory.getBean(“user”);


public class DependencyLookupDemo {

    public static void main(String[] args) {
        // 配置 XML 配置文件
        // 启动 Spring 应用上下文
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/meta-INF/dependency-lookup-context.xml");
        lookupInRealTime(beanFactory);
        lookupInLazy(beanFactory);
    }

    private static void lookupInLazy(BeanFactory beanFactory) {
        
         //区别在这里!!
        ObjectFactory objectFactory = (ObjectFactory) beanFactory.getBean("objectFactory");
        User user = objectFactory.getObject();
        System.out.println("延迟查找:" + user);
    }

    private static void lookupInRealTime(BeanFactory beanFactory) {

      
        //区别在这里!!
        User user = (User) beanFactory.getBean("user");
        System.out.println("实时查找:" + user);
    }
    }
2 通过类型查找

如:beanFactory.getBean(User.class);

 
public class DependencyLookupDemo {

    public static void main(String[] args) {
        // 配置 XML 配置文件
        // 启动 Spring 应用上下文
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/meta-INF/dependency-lookup-context.xml");
        // 按照类型查找
        lookupByType(beanFactory);
        // 按照类型查找结合对象
        lookupCollectionByType(beanFactory);
    }

    private static void lookupByType(BeanFactory beanFactory) {
        //区别在这里!!
        User user = beanFactory.getBean(User.class);
        System.out.println("按照类型查找:" + user);
    }

    private static void lookupCollectionByType(BeanFactory beanFactory) {
         //区别在这里!!
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            Map users = listableBeanFactory.getBeansOfType(User.class);
            System.out.println("查找到的所有的 User 集合对象:" + users);
        }
    }
}
3 通过注解查找

前置工作:先写一个自定义注解,然后标注在一个新的类上,并在xml上声明好
a : 自定义注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Super {
}

b: 标注在一个新的类上

@Super
public class SuperUser extends User {

    private String address;

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "SuperUser{" +
                "address='" + address + ''' +
                "} " + super.toString();
    }
}

c : 声明

 
        

d : 查找

public class DependencyLookupDemo {

    public static void main(String[] args) {
        // 配置 XML 配置文件
        // 启动 Spring 应用上下文
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/meta-INF/dependency-lookup-context.xml");
        // 通过注解查找对象
        lookupByAnnotationType(beanFactory);
    }

    private static void lookupByAnnotationType(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            Map users = (Map) listableBeanFactory.getBeansWithAnnotation(Super.class);
            System.out.println("查找标注 @Super 所有的 User 集合对象:" + users);
        }
    }
}
依赖注入示例 手动方式

写在xml 配置里,不灵活

    
     ` 
    
        
            
                
                
            
        
    `
 
自动配置

主要是autowire 属性

   
 
依赖注入和查找的对象来自于哪里

a : 自定义bean
b :容器内建Bean 对象 ,例如
Environment environment =applicationContext.getBean(Environment.class);
c : 容器内建依赖

配置元信息

Bean 定义配置: (Bean 相关的配置)
基于XML文件,基于Propertiles文件,基于Java 注解,基于 Java API

IOC 容器的配置 (容器相关的配置)
基于 XML 文件,基于Java 注解, 基于 Java API

外部化的配置
基于Java 注解

Spring IOC 容器生命周期

待补充

总结

本文主要讲IOC ,以及在Spring 里 IOC 设计思想的具体体现。进而更具体的讲 Spring 代码里 IOC 是如何进行依赖注入,如果进行依赖查找的,是否可以通过配置方式进行调整(配置元信息) ,对象是哪里来的,对象是谁控制的,以及对象整个过程的声明周期是如何管理的。
按照这样的思路,IOC 的基本面应该都有所涉及了。接下来就是针对各个点去进行深入的立即和学习。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5717671.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存