zoukankan      html  css  js  c++  java
  • Spring(03)Spring IOC 概述

    Spring(03)Spring IOC 概述

    Spring 核心编程思想目录:https://www.cnblogs.com/binarylei/p/12290153.html

    1. Spring IoC 依赖查找

    1.1 根据 Bean 名称查找

    • 实时查找

      User user = (User) beanFactory.getBean("user");
      
    • 延迟查找

      bean 配置如下:

      <bean id="user1" class="com.binarylei.spring.ioc.bean.User" lazy-init="true"/>
      <bean id="user2" class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
          <property name="targetBeanName" value="user1"/>
      </bean>
      

      通过 ObjectFactory 获取 bean 时会延迟加载 bean,只有手动调用 getObject 方法都会初始化 User 对象。将 User 设置为 lazy-init="true" 效果会更明显,Spring 会默认初始化所有非懒加载的 bean。

      ObjectFactory<User> objectFactory = (ObjectFactory) beanFactory.getBean("user2");
      User user = objectFactory.getObject();
      

    思考: ObjectFactory 和 FactoryBean 都是通过 getObject 创建对象,它们有什么区别呢?

    1. ObjectFactory :是属于懒加载 bean,只有手动调用 getObject 都会初始化 bean。

    2. FactoryBean:当加载 FactoryBean 的同时就会调用 getObject 初始化对象,不属于懒加载 bean。Spring 中如果想要获取 FactoryBean 本身,可以在 bean 名称前加载 & 符号。

      FactoryBean<User> factoryBean = (FactoryBean<User>) beanFactory.getBean("&user");

    1.2 根据 Bean 类型查找

    • 单个 Bean 对象

      User user = beanFactory.getBean(User.class);
      
    • 集合 Bean 对象

      Map<String, User> userMap = ((DefaultListableBeanFactory) beanFactory)
          .getBeansOfType(User.class);
      

    思考: beanFactory.getBean(User.class),如果返回多个对象,Spring 会如何处理,如何解决?

    当 Spring 容器中有多个 User 对象时,Spring 会抛出异常 NoUniqueBeanDefinitionException,这时可以通过标注 primary 来处理。

    <bean id="user1" class="com.binarylei.spring.ioc.bean.User" primary="true"/>
    

    1.3 根据 Bean 名称 + 类型查找

    User user = beanFactory.getBean("user", User.class);
    

    1.4 根据 Java 注解查找

    Map<String, Object> beanMap = ((DefaultListableBeanFactory) beanFactory)
        .getBeansWithAnnotation(Component.class);
    

    2. Spring IoC 依赖注入

    有 UserManager 类,如何将 users 注入呢?

    @Data
    public class UserManager {
        private BeanFactory beanFactory;
        private SuperUser superUser;
        private List<User> users;
    } 
    

    2.1 根据 Bean 名称注入

    • 单个Bean 对象

      <bean id="userManager" class="com.binarylei.spring.ioc.bean.UserManager">
          <property name="superUser" ref="user"/>
      </bean>
      
    • 集合 Bean 对象

      <bean id="userManager" class="com.binarylei.spring.ioc.bean.UserManager">
          <property name="users">
              <util:list>
                  <ref bean="user1"/>
                  <ref bean="user2"/>
              </util:list>
          </property>
      </bean>
      

    2.2 根据 Bean 类型注入

    <bean id="userManager" class="com.binarylei.spring.ioc.bean.UserManager" 
          autowire="byType"/>
    

    2.3 注入容器內建 Bean 对象

    如 Environment 对象。

    2.4 注入非 Bean 对象

    如 BeanFacory 可以正常注入到 UserManager 中。如果通过 beanFactory.getBean(BeanFactory.class) 会抛出 NoSuchBeanDefinitionException 异常。

    2.5 注入类型

    • 实时注入
    • 延迟注入

    2.6 注入模式

    • 手动模式- 配置或者编程的方式,提前安排注入规则
      • XML 资源配置元信息
      • Java 注解配置元信息
      • API 配置元信息
    • 自动模式- 实现方提供依赖自动关联的方式,按照內建的注入规则
      • Autowiring(自动绑定):no、byName、byType、constructor

    3. Spring IoC 依赖来源

    • 自定义 Bean
    • 容器內建 Bean 对象
    • 容器內建依赖

    4. Spring IoC 配置元信息

    • Bean 定义配置

      • 基于 XML 文件
      • 基于 Properties 文件
      • 基于 Java 注解
      • 基于 Java API(专题讨论)
    • IoC 容器配置

      • 基于 XML 文件
      • 基于 Java 注解
      • 基于 Java API (专题讨论)
    • 外部化属性配置

      • 基于Java 注解,@Value 注解

    5. Spring IoC 容器

    • BeanFactory 是 Spring 底层 IoC 容器。
    • ApplicationContext 是具备应用特性的 BeanFactory 超集。

    ApplicationContext 除了IoC 容器角色,还有提供:

    • 面向切面(AOP)
    • 配置元信息(Configuration Metadata)
    • 资源管理(Resources)
    • 事件(Events)
    • 国际化(i18n)
    • 注解(Annotations)
    • Environment 抽象(Environment Abstraction)
    public interface ApplicationContext extends EnvironmentCapable,
         ListableBeanFactory, HierarchicalBeanFactory, MessageSource, 
        ApplicationEventPublisher, ResourcePatternResolver {
    }
    

    6. Spring 应用上下文

    ApplicationContext

    https://docs.spring.io/spring/docs/5.2.2.RELEASE/spring-framework-reference/core.html#beans-introduction

    7. Spring IoC 容器生命周期

    • 启动
    • 运行
    • 停止
    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            prepareBeanFactory(beanFactory);
            try {
                postProcessBeanFactory(beanFactory);
                invokeBeanFactoryPostProcessors(beanFactory);
                registerBeanPostProcessors(beanFactory);
                initMessageSource();
                initApplicationEventMulticaster();
                onRefresh();
                registerListeners();
                finishBeanFactoryInitialization(beanFactory);
                finishRefresh();
            } catch (BeansException ex) {
                destroyBeans();
                cancelRefresh(ex);
                throw ex;
            } finally {
                resetCommonCaches();
            }
        }
    }
    

    8. 面试题精选

    问题1:什么是 Spring IoC 容器?

    问题2:BeanFactory 与FactoryBean?

    • BeanFactory 是IoC 底层容器。
    • FactoryBean 是创建Bean 的一种方式,帮助实现复杂的初始化逻辑。

    问题3:Spring IoC 容器启动时做了哪些准备?

    IoC 配置元信息读取和解析、IoC 容器生命周期、Spring 事件发布、国际化等,更多答案将在后续专题章节逐一讨论


    每天用心记录一点点。内容也许不重要,但习惯很重要!

  • 相关阅读:
    移动开发 Native APP、Hybrid APP和Web APP介绍
    urllib与urllib2的学习总结(python2.7.X)
    fiddler及postman讲解
    接口测试基础
    UiAutomator2.0 和1.x 的区别
    adb shell am instrument 命令详解
    GT问题记录
    HDU 2492 Ping pong (树状数组)
    CF 567C Geometric Progression
    CF 545E Paths and Trees
  • 原文地址:https://www.cnblogs.com/binarylei/p/12296907.html
Copyright © 2011-2022 走看看