• Spring Framework之IoC容器





    Spring IoC 概述

    问题

    1.什么是依赖倒置?

    2.什么是控制反转?

    3.什么是依赖注入?

    4.它们之间的关系是怎样的?

    5.优点有哪些?

    依赖倒置原则 (Dependency Inversion Principle)

    依赖倒置是一种设计原则。

    ​ 依赖倒置包括三层含义:(1)高层模块不应该直接依赖于底层模块,两者都应依赖其抽象;(2)抽象不应依赖于细节;(3)细节应该依赖于抽象。

    控制反转 (Inversion of Control)

    控制反转是一种思想。其核心思想在于,合作的对象依赖关系的管理不由具体对象来完成,而是具体对象交出依赖关系的控制权,由第三方容器来集中管理。

    ​ 第三方容器管理的优点:(1)依赖关系的集中管理,关系清晰且易管理;(2)降低合作对象之间的耦合程度。

    ​ 举个栗子。我想在北京租一间房子,我只需要把我的需求告知链家等中介公司,通过他们整合的资源,我就能够找到一间符合我需求的房子。我不需要与房东产生任何直接的关系,中间的任何问题都由链家进行统一处理。在这个例子中,房客与房东是两个独立的对象,而链家则是充当中间容器

    依赖注入(Dependency Inversion)

    依赖注入是控制反转的具体方法之一。依赖注入就是将底层依赖对象以参数形式传入上层对象。

    ​ 对象间的依赖关系的管理被反转至IoC容器中。对象间的依赖关系由IoC容器进行统一管理,并由IoC容器来完成对象的注入。

    依赖倒置原则 、控制反转 、依赖注入的关系

    DIP、IoC、DI关系图

    优点

    1.实现模块间松耦合

    2.由IoC容器来统一管理依赖关系,对象从复杂的依赖关系中解放。

    3.对象自身弄够专注于自身功能上,不需要了解依赖对象的内部结构。



    IoC 容器

    BeanFactory3

    BeanFactory

    BeanFactory4

    BeanFactory提供最基本的IoC容器功能和基本规范。

    ​ BeanFactory中有getBean、getType、getAliases、isSingleton、isPrototype等函数。主要常用接口是getBean,改函数能够通过Bean名称获取Bean

    BeanFactory扩展接口

    (1)ListableBeanFactory:接口定义Bean的基本信息。

    ​ 接口中函数有:getBeanDefinitionCount获取Bean数量、containsBeanDefinition判断容器中是否存在该Bean、getBeanDefinitionNames获取工程所有Bean的名称等。

    (2)HierarchicalBeanFactory:父子容器关联

    ​ 接口中函数有:getParentBeanFactory子容器可以通过函数访问到父容器

    (3)ConfigurableBeanFactory:可定制IoC容器

    ​ 接口中函数有:setBeanClassLoader设置Bean类加载器、setBeanExpressionResolver设置表达式解析器、registerCustomEditor注册编辑器等。

    (4)AutowireCapableBeanFactory:定义Bean自动装配规则

    ​ 接口中函数有:autowireBeanProperties根据名称或属性给Bean进行自动装配等。

    ApplicationContext

    ApplicationContext关系图

    ApplicationContext基于BeanFactory,是比BeanFactory更为高级的容器。

    ​ ApplicationContext相对于BeanFactory提供更多功能,BeanFactory中需要通过编程实现的功能,ApplicationContext中可以使用配置来实现。

    ​ ApplicationContext继承ListableBeanFactory、HierarchicalBeanFactory,除此之外还扩展了其他接口。

    ApplicationContext扩展接口:

    (1)ApplicationEventPublisher:封装事件发布功能。

    (2)MessageSource:提供i18n国际化消息刚问功能。(解释模块中解释i18n)

    (3)ResourcePatternResolver:通过路径加载资源

    (4)LifeCycle:start()、stop()、isRunning(),控制与判断容器当前状态,以达到控制与调度的作用。

    (5)ConfigurableApplicationContext:实现ApplicationContext,新增refresh()、close(),使ApplicationContext具备启动、刷新、关闭等功能。



    IoC容器的依赖注入

    基于注解定义Bean

    ​ Spring2.0开始Spring提供基于注解的依赖注入功能。使用xml进行配置使Bean定义信息与Bean实现代码分离,这就会造成代码复杂且易错。基于注解就可以在Bean实现类上进行注解标注,这大大降低的代码的复杂性。

    ​ 定义Bean注解有以下4中:

    ​ (1)@Component:组件

    ​ (2)@Respository:对于Dao实现类进行标注

    ​ (3)@Service:对于Service实现类进行标注

    ​ (4)@Controller:对于Controller实现类进行标注

    @Respository、@Service、@Controller是@Component的扩展,尽量使用3种特殊的注解,因为能够标识出Bean的类型。

    自动装配

    @Resource

    ​ resource是用J2EE提供的。

    查找方式:

    (1)按照指定name和type,容器中找到后对bean进行装配,找不到抛出异常。

    (2)按照指定name,容器中找到后对bean进行装配,找不到抛出异常。

    (3)按照指定type,容器中找到后对bean进行装配,找不到或找到多个抛出异常。

    (4)没指定name和type,则先安装name方式装配,找不到这则按type进行装配,都没有抛异常。

    @Autowired

    ​ autowired是spring提供的。

    查找方式:

    (1)按照类型查找,如果该类型bean不唯一则抛异常。

    @Qualifier

    查找方式:

    (1)通过名称指定Bean,同一个接口有多个实现,我们要装配其中某一个Bean时,可以用qualifier通过名称直接指定,一般结合Autowired一起使用。

    基于Java类配置

    @Bean

    ​ 普通的POJO可以通过标注@Configuration注解,就可以为Spring容器提供Bean定义信息,标注了@Bean的类方法就相当于提供了Bean的定义信息。当第三方库引入时,可以使用@Bean注解将Bean交由Spring容器进行管理。

    @Configuration
    public class AppConfig {
    
        @Bean(name = "dataSource")
        public DataSource initDataSource() {
            return DataSourceBuilder.create().build();
        }
    }
    

    相当于

    <beans>
        <bean id="dataSource" class="org.springframework.boot.jdbc.DataSourceBuilder"/>
    </beans>
    



    Bean的作用域

    类型 说明
    singleton IoC容器中仅存在一个Bean实例
    prototype 每次调用都会返回新的Bean实例
    request 每次Http请求都会创建一个Bean
    session 同一个session共享Bean
    globalSession 同一个全局Session共享一个Bean

    singleton

    singleton

    prototype

    prototype



    FactoryBean

    解释说明

    ​ FactoryBean是能够生产和修饰对象生成的工厂Bean。Spring提供了org.springframework.beans.factory. FactoryBean接口,使用者能通过实现接口对Bean的实例化进行定制。

    使用场景

    (1)第三方框架提供的类,我们很难直接修改类代码,为其添加@Service或@Componet时。
    (2)当我们需要对第三方框架生成的实例进行修饰时。

    应用案例

    (1) mybatis-spring中org.mybatis.spring.SqlSessionFactoryBean



    IoC容器内部关系

    Spring容器、配置文件、Bean、应用程序关系图

    ​ Bean配置信息配置了Bean的实现与依赖关系,容器将Bean配置信息注册至注册表中,然后根据注册表加载与实例化,并建立Bean与Bean之间的依赖关系,最后将结果放置Bean缓存池中,供用应用程序调用。



    JSR-250注释

    JSR-250注释包括@PostConstruct,@PreDestroy,@Resource。@PostConstruct与@PreDestroy不用于依赖注入,用于标注对象生命周期的管理方法。

    @Resource

    ​ @Resource与@Autowired的区别在上文已经讲过就不再赘述。

    @PostConstruct

    如果想要在对象实例化后做一些准备工作,可以使用@PostConstruct。

        @Resource
        private ADRFingerprintBuilder adrFingerprintBuilder;
    
        @Resource
        private IOSFingerprintBuilder iosFingerprintBuilder;
    
        @Resource
        private List<ADRChecker> adrCheckers;
    
        @Resource
        private List<IOSChecker> iosCheckers;
    
        private static Map<String, EventTemplate> event = new HashMap<>();
    
        @PostConstruct
        public void buildEventMap() {
            event.put(ClientSourceEnum.ADR.getSource(), EventTemplate.builder().builder(adrFingerprintBuilder).checkers(adrCheckers).build());
            event.put(ClientSourceEnum.IOS.getSource(), EventTemplate.builder().builder(iosFingerprintBuilder).checkers(iosCheckers).build());
        }
    

    ​ 在完成实例化后,将实例放入map中,为后续操作做准备工作。

    @PreDestroy

    ​ 在对象销毁之前调用方法关闭资源或其他动作可以使用@PreDestroy。

    @PreDestroy
       public void destroy(){
          System.out.println("destroy");
       }
    



    解释

    1. i18n:国际化信息也称为本地化信息 。 Java 通过 java.util.Locale 类来表示本地化对象,它通过 “语言类型” 和 “国家/地区” 来创建一个确定的本地化对象。比如在发送一个具体的请求的时候,在header中设置一个键值对:"Accept-Language":"zh",通过Accept-Language对应值,服务器就可以决定使用哪一个区域的语言,找到相应的资源文件,格式化处理,然后返回给客户端。



    参考

    [1]https://www.jianshu.com/p/6f0a59623090

    [2]https://www.cnblogs.com/hujunzheng/p/11037577.html

    [3]《精通Spring4.x企业应用开发实战》

    [4]《Spring揭秘》

  • 相关阅读:
    学习Timer定时器
    C++ 延时等待(sleep/timer/wait)
    MFC学习问题总结
    node.js
    总结
    关于Windows
    关于数组
    每周一次
    每周一次
    每周一次
  • 原文地址:https://www.cnblogs.com/boycelee/p/12635640.html
Copyright © 2020-2023  润新知