Spring IoC 依赖查找

第五章 Spring 依赖查找.pdf

单一类型查找 - BeanFactory

  • 根据Bean名称查找
    • getBean(String)
    • Spring 2.5覆盖默认参数:getBean(String,Object…)
  • 根据Bean类型查找

    • Bean实时查找
      • Spring 3.0getBean(Class)
      • Spring 4.1覆盖默认参数:getBean(Class,Object…)
    • Spring 5.1Bean延迟查找
      • getBeanProvider(Class)
      • getBeanProvider(ResolvableType)
        1. private static void beanFactoryLookupDemo(BeanFactory beanFactory) {
        2. // 根据名称实时查找
        3. System.out.println(beanFactory.getBean("user"));
        4. // 根据类型实时查找
        5. System.out.println(beanFactory.getBean(User.class));
        6. // 根据类型延迟查找
        7. ObjectProvider<User> beanProvider = beanFactory.getBeanProvider(User.class);
        8. System.out.println(beanProvider.getObject());
        9. }
  • 根据Bean名称+类型查找:getBean(String,Class)

    集合类型查找 - ListableBeanFactory

  • 根据Bean类型查找

    • 获取同类型Bean名称列表
      • getBeanNamesForType(Class)
      • Spring 4.2getBeanNamesForType(ResolvableType)
    • 获取同类型Bean实例列表
      • getBeansOfType(Class)以及重载方法
  • 通过注解类型查找

    • Spring 3.0获取标注类型Bean名称列表
      • getBeanNamesForAnnotation(Class<? extends Annotation>)
    • Spring 3.0获取标注类型Bean实例列表
      • getBeansWithAnnotation(Class<? extends Annotation>)
    • Spring 3.0获取指定名称+标注类型Bean实例

      • findAnnotationOnBean(String,Class<? extends Annotation>) ```java private static void listableBeanFactoryDemo(ListableBeanFactory listableBeanFactory) { // 根据类型获取所有同类型Bean System.out.println(listableBeanFactory.getBeansOfType(User.class));

      // 获取有指定注解的全部Bean System.out.println(listableBeanFactory.getBeansWithAnnotation(Vip.class)); } ```

      层次性依赖查找 - HierarchicalBeanFactory

  • 双亲BeanFactory:getParentBeanFactory()

  • 层次性查找

    • 根据Bean名称查找

      • 基于containsLocalBean方法实现 ```java public static void main(String[] args) {

      AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class); context.setParent(new ClassPathXmlApplicationContext(“classpath:META-INF/dependency-lookup-context.xml”)); hierarchicalBeanFactoryDemo(context); }

private static void hierarchicalBeanFactoryDemo(HierarchicalBeanFactory hierarchicalBeanFactory) { // getParentBeanFactory HierarchicalBeanFactory parentBeanFactory = (HierarchicalBeanFactory) hierarchicalBeanFactory.getParentBeanFactory(); System.out.println(parentBeanFactory.getBean(User.class)); System.out.println(parentBeanFactory.containsLocalBean(“user”)); System.out.println(parentBeanFactory.containsBean(“user”)); }

  1. - 根据Bean类型查找实例列表
  2. - 单一类型:BeanFactoryUtils#beanOfType
  3. - 集合类型:BeanFactoryUtils#beansOfTypeIncludingAncestors
  4. - 根据Java注解查找名称列表
  5. - BeanFactoryUtils#beanNamesForTypeIncludingAncestors
  6. ```java
  7. private static void beanFactoryUtilsDemo(ListableBeanFactory listableBeanFactory){
  8. System.out.println(BeanFactoryUtils.beanOfType(listableBeanFactory,UserVip.class));
  9. System.out.println(BeanFactoryUtils.beansOfTypeIncludingAncestors(listableBeanFactory, User.class));
  10. System.out.println(Arrays.toString(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(listableBeanFactory, User.class)));
  11. }

延迟依赖查找

  • org.springframework.beans.factory.ObjectFactory
  • org.springframework.beans.factory.ObjectProvider

    • Spring 5对Java 8特性扩展
      • 函数式接口
        • getIfAvailable(Supplier)
        • ifAvailable(Consumer)
      • Stream扩展- stream()

        安全依赖查找

        image.png

        内建可查找依赖

        image.png
        image.png
        image.png

        依赖查找中的异常

        image.png

        面试题

  • ObjectFactory与BeanFactory的区别?

答:ObjectFactory与BeanFactory均提供依赖查找的能力。不过ObjectFactory仅关注一个或一种类型的Bean依赖查找,并且自身不具备依赖查找的能力,能力则由BeanFactory输出。BeanFactory则提供了单一类型、集合类型以及层次性等多种依赖查找方式。

  • BeanFactory.getBean操作是否线程安全?

BeanFactory.getBean方法的执行是线程安全的,操作过程中会增加互斥锁