第三章 Spring IoC 概述.pdf

Spring IoC 概述

Spring IoC依赖查找

  • 根据Bean名称查找
    • 实时查找
  • 根据Bean类型查找
    • 延迟查找
    • 单个Bean对象
    • 集合Bean对象
  • 根据Bean名称+类型查找
  • 根据Java注解查找

    • 单个Bean对象
    • 集合Bean对象 ```java /*

      • 依赖查找示例
      • 1、根据名称即时查找查找
      • 2、根据类型即时查找查找
      • 3、根据类型延迟查找
      • 4、根据类型查找集合
      • 5、根据注解查找集合 *
      • @author :Administrator
      • @date :2022/4/8 0008 */ public class DependencyLookupDemo {

      public static void main(String[] args) { BeanFactory beanFactory = new ClassPathXmlApplicationContext(“classpath:META-INF/dependency-lookup-context.xml”);

      // 根据名称实时查找Bean lookupByNameInRealTime(beanFactory); // 根据类型延迟查找Bean lookupByTypeInLazy(beanFactory); // 根据类型实时查找Bean lookupByTypeInRealTime(beanFactory); // 根据类型查找Bean集合 lookupCollectionByType(beanFactory); // 根据注解查找Bean集合 lookupByAnnotationType(beanFactory);

      }

      /**

      • 根据名称即时查找Bean */ private static void lookupByNameInRealTime(BeanFactory beanFactory) { User user = (User) beanFactory.getBean(“user”); System.out.println(“根据名称即时查找:” + user); }

      /**

      • 根据类型,延迟查找Bean {@link BeanFactory} *
      • @see ObjectFactory */ private static void lookupByTypeInLazy(BeanFactory beanFactory) { ObjectFactory userFactory = beanFactory.getBeanProvider(User.class); User user = userFactory.getObject(); System.out.println(“根据类型延迟查找:” + user); }

      /**

      • 根据类型实时查找Bean */ private static void lookupByTypeInRealTime(BeanFactory beanFactory) { User user = beanFactory.getBean(User.class); System.out.println(“根据类型实时查找:” + user); }

      /**

      • 根据类型查找Bean集合 {@link ListableBeanFactory#getBeansOfType(Class)} */ private static void lookupCollectionByType(BeanFactory beanFactory) { if (beanFactory instanceof ListableBeanFactory) {
        1. ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
        2. Map<String, User> map = listableBeanFactory.getBeansOfType(User.class);
        3. System.out.println("根据类型查找Bean集合");
        4. map.forEach((beanName, user) -> System.out.println(beanName + ":" + user));
        } }

      /**

      • 根据注解类型查找Bean {@link ListableBeanFactory#getBeansWithAnnotation(Class)} */ private static void lookupByAnnotationType(BeanFactory beanFactory) { if (beanFactory instanceof ListableBeanFactory) {
         ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
         Map<String, User> map = (Map) listableBeanFactory.getBeansWithAnnotation(Super.class);
         System.out.println("根据注解查找Bean集合");
         map.forEach((beanName,bean)-> System.out.println(beanName+" : "+bean));
        
        } } }
<a name="p1YiV"></a>
## Spring IoC依赖注入

- **根据Bean名称注入**
- **根据Bean类型注入**
   - 单个Bean对象
   - 集合Bean对象
- **注入容器內建Bean对象**
- **注入非Bean对象**
- **注入类型**
   - 实时注入
   - 延迟注入
<a name="hCDxm"></a>
## Spring IoC依赖来源

- 自定义Bean
- 容器内建Bean
- 容器内建依赖
```java
public class DependencyInjectionDemo {
    public static void main(String[] args) {
       // BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:META-INF/dependency-injection-context.xml");
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:META-INF/dependency-injection-context.xml");

        //依赖来源1:自定义Bean
        UserRepository userRepository = (UserRepository) applicationContext.getBean(UserRepository.class);

        //依赖来源2: 内建依赖
        System.out.println(userRepository.getBeanFactory());
        System.out.println(userRepository.getObjectFactory().getObject());

        // 依赖来源3:容器内建Bean
        System.out.println(applicationContext.getBean(Environment.class));
    }
}

Spring IoC配置元信息

Bean定义配置

  • 基于XML文件
  • 基于Properties文件
  • 基于Java注解
  • 基于Java API(专题讨论)

IoC容器配置

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

    Spring IoC容器

    BeanFactory和ApplicationContext谁才是Spring IoC容器?
    BeanFactory 是IoC底层实现,ApplicationContext是在BeanFactory基础上进行增加特性:

  • 更容易与Spring的AOP特性集成

  • 消息资源处理(用于国际化)
  • 事件发布
  • 应用层特定上下文,如web应用中使用的WebApplicationContext

BeanFactory提供了配置框架和基本功能,而ApplicationContext添加了更多特定于企业的功能。ApplicationContext是BeanFactory的一个完整的超集。

Spring应用上下文

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

  • 面向切面(AOP)
  • 配置元信息(Configuration Metadata)
  • 资源管理(Resources)
  • 事件(Events)
  • 国际化(i18n)
  • 注解(Annotations)
  • Environment抽象(Environment Abstraction)

    使用Spring IoC容器

  • BeanFactory是Spring底层IoC容器

  • ApplicationContext是具备应用特性的BeanFactory超集

    Spring IoC容器生命周期

    启动(refresh())

    @Override
    public void refresh() throws BeansException, IllegalStateException {
      synchronized (this.startupShutdownMonitor) {
          // Prepare this context for refreshing.
          prepareRefresh();
    
          // Tell the subclass to refresh the internal bean factory.
          ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
          // Prepare the bean factory for use in this context.
          prepareBeanFactory(beanFactory);
    
          try {
              // Allows post-processing of the bean factory in context subclasses.
              postProcessBeanFactory(beanFactory);
    
              // Invoke factory processors registered as beans in the context.
              invokeBeanFactoryPostProcessors(beanFactory);
    
              // Register bean processors that intercept bean creation.
              registerBeanPostProcessors(beanFactory);
    
              // Initialize message source for this context.
              initMessageSource();
    
              // Initialize event multicaster for this context.
              initApplicationEventMulticaster();
    
              // Initialize other special beans in specific context subclasses.
              onRefresh();
    
              // Check for listener beans and register them.
              registerListeners();
    
              // Instantiate all remaining (non-lazy-init) singletons.
              finishBeanFactoryInitialization(beanFactory);
    
              // Last step: publish corresponding event.
              finishRefresh();
          }
    
          catch (BeansException ex) {
              if (logger.isWarnEnabled()) {
                  logger.warn("Exception encountered during context initialization - " +
                          "cancelling refresh attempt: " + ex);
              }
    
              // Destroy already created singletons to avoid dangling resources.
              destroyBeans();
    
              // Reset 'active' flag.
              cancelRefresh(ex);
    
              // Propagate exception to caller.
              throw ex;
          }
    
          finally {
              // Reset common introspection caches in Spring's core, since we
              // might not ever need metadata for singleton beans anymore...
              resetCommonCaches();
          }
      }
    }
    

    运行
    停止 close()

    /**
    * Close this application context, destroying all beans in its bean factory.
    * <p>Delegates to {@code doClose()} for the actual closing procedure.
    * Also removes a JVM shutdown hook, if registered, as it's not needed anymore.
    * @see #doClose()
    * @see #registerShutdownHook()
    */
    @Override
    public void close() {
      synchronized (this.startupShutdownMonitor) {
          doClose();
          // If we registered a JVM shutdown hook, we don't need it anymore now:
          // We've already explicitly closed the context.
          if (this.shutdownHook != null) {
              try {
                  Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
              }
              catch (IllegalStateException ex) {
                  // ignore - VM is already shutting down
              }
          }
      }
    }
    

    面试题精选

  • 什么是Spring IoC容器

Spring框架实现的反转控制(IoC)原则。IoC也称为依赖项注入(DI)。在这个过程中,对象只能通过构造函数参数、工厂方法的参数或在对象实例被构造或从工厂方法返回后在对象实例上设置的属性来定义它们的依赖关系(即它们所处理的其他对象)。容器然后在创建bean时注入这些依赖项。

  • BeanFactory与FactoryBean?
    答:BeanFactory是IoC底层容器。

FactoryBean是创建Bean的一种方式,帮助实现复杂的初始化逻辑

  • Spring IoC容器启动时做了哪些准备?

答:IoC配置元信息读取和解析、IoC容器生命周期、Spring事件发布、国际化等