Spring编程核心思想-第三章

Spring IOC容器概述

Spring IoC依赖查找:依赖注入还不够吗?依赖查找存在的价值几何?

  • 根据 Bean 名称查找
    • 实时查找
    • 延迟查找
    /**
     * 延迟查找:使用ObjectFactory进行包装
     **/
	public void lookupInLazy(BeanFactory beanFactory) {
	        ObjectFactory<User> objectFactory = (ObjectFactory<User>) beanFactory.getBean("objectFactory");
	        User user = objectFactory.getObject();
	        System.out.println("延迟查找:" + user);
    }
    /**
     * 实时查找:使用ObjectFactory进行包装
     **/
    public void lookupInRealTime(BeanFactory beanFactory) {
        User user = (User) beanFactory.getBean("user");
        System.out.println("实时查找:" + user);
    }
  • 根据 Bean 类型查找
    • 单个 Bean 对象
    • 集合 Bean 对象
    /**
    * ListableBeanFactory 查找集合 Bean 对象
    **/
	public void lookupCollectionByType(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            Map<String, User> users = listableBeanFactory.getBeansOfType(User.class);
            System.out.println("查找到的所有的 User 集合对象:" + users);
        }
    }
    /**
     * 实时查找:单个 Bean 对象
    **/
    public void lookupByType(BeanFactory beanFactory) {
        User user = beanFactory.getBean(User.class);
        System.out.println("实时查找:" + user);
    }
  • 根据 Bean 名称 + 类型查找
  • 根据 Java 注解查找
    • 单个 Bean 对象
    • 集合 Bean 对象
    /**
     * 通过注解查找对象
    **/
    public void lookupByAnnotationType(BeanFactory beanFactory) {
        if (beanFactory instanceof ListableBeanFactory) {
            ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
            Map<String, User> users = (Map) listableBeanFactory.getBeansWithAnnotation(Super.class);
            System.out.println("查找标注 @Super 所有的 User 集合对象:" + users);
        }
    }

Spring IoC依赖注入:Spring提供了哪些依赖注入模式和类型呢?

  • 根据 Bean 名称注入
  • 根据 Bean 类型注入
    • 单个 Bean 对象
    • 集合 Bean 对象
    <bean id="userRepository" class="org.wangjzm.thinking.in.spring.ioc.overview.repository.UserRepository"
          autowire="byType"> <!-- Auto-Wiring -->
        <!-- 手动配置 -->
        <!--        <property name="users">-->
        <!--            <util:list>-->
        <!--                <ref bean="superUser" />-->
        <!--                <ref bean="user" />-->
        <!--            </util:list>-->
        <!--        </property>-->

    </bean>
  • 注入容器內建 Bean 对象
  • 注入非 Bean 对象
  • 注入类型
    • 实时注入
    • 延迟注入

Spring IoC依赖来源:依赖注入和查找的对象来自于哪里?

/**
* UserRepository 实体类
**/
public class UserRepository {

    private Collection<User> users; // 自定义 Bean

    private BeanFactory beanFactory; // 內建非 Bean 对象(依赖)

    private ObjectFactory<ApplicationContext> objectFactory;

    public Collection<User> getUsers() {
        return users;
    }

    public void setUsers(Collection<User> users) {
        this.users = users;
    }


    public void setBeanFactory(BeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }

    public ObjectFactory<ApplicationContext> getObjectFactory() {
        return objectFactory;
    }

    public void setObjectFactory(ObjectFactory<ApplicationContext> objectFactory) {
        this.objectFactory = objectFactory;
    }
}
  • 自定义 Bean

  • 容器內建 Bean 对象

  • 容器內建依赖

public class DependencyInjectionDemo {

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

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-injection-context.xml");

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

//        System.out.println(userRepository.getUsers());

        // 依赖来源二:依赖注入(內建依赖)
        System.out.println(userRepository.getBeanFactory());


        ObjectFactory userFactory = userRepository.getObjectFactory();
        
        // true 
        System.out.println(userFactory.getObject() == applicationContext);

        // 依赖查找(错误)
//        System.out.println(beanFactory.getBean(BeanFactory.class));

        // 依赖来源三:容器內建 Bean
        Environment environment = applicationContext.getBean(Environment.class);
        System.out.println("获取 Environment 类型的 Bean:" + environment);
    }

    private static void whoIsIoCContainer(UserRepository userRepository, ApplicationContext applicationContext) {
        // ConfigurableApplicationContext <- ApplicationContext <- BeanFactory
        
        // ConfigurableApplicationContext#getBeanFactory()
		
		// ApplicationContext is BeanFactory

        // false,这个表达式为什么不会成立?
        // 原因:userRepository.getBeanFactory()获取的BeanFactory和aplicationContext
        // 是两个不同的对象,aplicationContext中组合了BeanFactory,类似于代理,之后从
        // applicationContext中调用getBean()方法其实就是调用组合对象BeanFactory的getBean()方法
        System.out.println(userRepository.getBeanFactory() == applicationContext);
        
    }

Spring IoC配置元信息:Spring IoC有哪些配置元信息?它们的进化过程是怎样的?

  • Bean 定义配置
    • 基于 XML 文件
    • 基于 Properties 文件
    • 基于 Java 注解
    • 基于 Java API(专题讨论)
  • IoC 容器配置
    • 基于 XML 文件
    • 基于 Java 注解
    • 基于 Java API (专题讨论)
  • 外部化属性配置
    • 基于 Java 注解

BeanFactory 和 ApplicationContext 谁才是 Spring IoC 容器?

两者都是,原因是上上章节代码中最后注释:
userRepository.getBeanFactory()获取的BeanFactory和aplicationContext是两个不同的对象aplicationContext中组合了BeanFactory,类似于代理,之后从applicationContext中调用getBean()方法其实就是调用组合对象BeanFactory的getBean()方法。

Spring应用上下文:ApplicationContext除了IoC容器角色,还提供哪些特性?

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

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

使用Spring IoC容器:选BeanFactory还是ApplicationContext?

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

Spring IoC容器生命周期:IoC容器启停过程中发生了什么?

之后再做详细分析。

面试题

  1. 什么是 Spring IoC 容器?
    答:Spring Framework implementation of the Inversion of
    Control (IoC) principle. IoC is also known as dependency
    injection (DI). It is a process whereby objects define their
    dependencies (that is, the other objects they work with) only
    through constructor arguments, arguments to a factory
    method, or properties that are set on the object instance after it
    is constructed or returned from a factory method. The container
    then injects those dependencies when it creates the bean.

  2. BeanFactory 与 FactoryBean?
    答: BeanFactory 是 IoC 底层容器
    FactoryBean 是 创建 Bean 的一种方式,帮助实现复杂的初始化逻辑

  3. Spring IoC 容器启动时做了哪些准备?
    答 :IoC 配置元信息读取和解析、IoC 容器生命周期、Spring 事件发布、国
    际化等,更多答案将在后续专题章节逐一讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值