Spring-依赖查找

依赖查找

根据名称进行查找

  • 实时查找
BeanFactory beanFactory = new ClassPathXmlApplicationContext("beans.xml");
Object bean = beanFactory.getBean("personHolder");
System.out.println(bean);

xml如下:

<bean id="person"  class="pojo.Person">
    <property name="name" value="yong"></property>
    <property name="id" value="1001"></property>
</bean>
<bean id="personHolder"  class="pojo.PersonHolder" >
    <property name="city" value="BEIJING"></property>
    <property name="person" ref="person"></property>
</bean>
  • 延迟查找
    所谓延迟查找其实就是我们使用到这个Bean的时候再去进行查找。
    通过xml配置的方式:
<!-- 这里指定了查找方式为延迟查找也就是说在需要用到这个bean的时候才会初始化 -->
<bean id="personHolder"  class="pojo.PersonHolder" lazy-init="true" init-method="init">
    <property name="city" value="BEIJING"></property>
    <property name="person" ref="person"></property>
</bean>

通过注解的方式:

@Bean
@Lazy
PersonHolder personHolder(Person person) {
   return new PersonHolder(person);
}

通过ObjectProvider的方式:

/**
* 也是延迟加载
* @param applicationContext
*/
private static void lookupIfAvailable(AnnotationConfigApplicationContext applicationContext) {
  ObjectProvider<PersonHolder> userObjectProvider = applicationContext.getBeanProvider(PersonHolder.class);
  PersonHolder personHolder = userObjectProvider.getIfAvailable(PersonHolder::createPersonHolder);
  System.out.println("当前 User 对象:" + personHolder);
}
public static void main(String[] args) {
  AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
  context.register(LookUpLazyByNameAnnotation.class);
  context.refresh();
  lookupIfAvailable(context);
}

除了getIfAvailable, ObjectProvider还提供了getIfUnique方法。

根据类型查找
  • 单个Bean
/**
 * 通过类型查找
 * @param beanFactory
 */
public static void lookUpByType(BeanFactory beanFactory) {
    Client bean = beanFactory.getBean(Client.class);
    System.out.println(bean);
}
  • 集合类型的查找
/**
 * 集合查找 ListableBeanFactory 实现了这个接口就可以进行集合查找
 * @param beanFactory
 */
public static void lookUpCollectionByType(BeanFactory beanFactory) {
    if (beanFactory instanceof ListableBeanFactory) {
        ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
        Map<String, Client> beansOfType = listableBeanFactory.getBeansOfType(Client.class);
        System.out.println(beansOfType);
    }
}

根据注解查找

  • 集合查找
/**
* 集合查找
* @param beanFactory
*/
public static void lookUpCollectionByAnnotation(BeanFactory beanFactory) {
   if (beanFactory instanceof ListableBeanFactory) {
       ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory;
       Map<String, Object> beansOfType = listableBeanFactory.getBeansWithAnnotation(Super.class);
       System.out.println(beansOfType);
   }
}

依赖查找详细版本

  • 单一类型依赖查找(主要是基于BeanFactory)
    根据Bean名称查找

  • getBean(String)

  • Spring 2.5 覆盖默认参数:getBean(String, Object)
    根据Bean类型查找
    Bean实时查找
    - Spirng 3.0getBean(Class)
    - Spring 4.1覆盖默认参数:getBean(Class, Object)
    Spring 5.1 Bean 延迟查找
    - getBeanProvider(Class)
    - getBeanProvider(ResolvableType)
    根据名称 + 类型查找 : getBean(Class, Name)
    JNDI - javax.naming.Context#lookup(javax.naming.Name)
    JavaBeans-java.beans.beancontext.BeanContext
    在这里插入图片描述

  • 集合类型依赖查找(Listable BeanFactory)

  • 根据 Bean 类型查找

    • 获取同类型 Bean 名称列表
      • getBeanNamesForType(Class)
      • Spring 4.2 getBeanNamesForType(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>)
  • 层次性依赖查找接口-HierarchicalBeanFactory
    双亲 BeanFactory:getParentBeanFactory()
    层次性查找
    根据 Bean 名称查找
    基于 containsLocalBean 方法实现
    根据 Bean 类型查找实例列表
    单一类型:BeanFactoryUtils#beanOfType
    集合类型:BeanFactoryUtils#beansOfTypelncludingAncestors
    根据 Java 注解查找名称列表
    BeanFactoryUtils#beanNamesForTypelncludingAncestors

public class Client {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context  = new AnnotationConfigApplicationContext();
        context.register(Client.class);
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 创建父亲工厂
        BeanFactory parent = createParent();
        // 设置父亲工厂
        beanFactory.setParentBeanFactory(parent);
        // 获取父工厂
        HierarchicalBeanFactory parentBeanFactory = (HierarchicalBeanFactory) beanFactory.getParentBeanFactory();
        // 父亲工厂查询
        disPlayLocalBean(parentBeanFactory, "user");
        // 当前工厂查询
        disPlayLocalBean(beanFactory, "user");
        // 双亲委派 当前工厂查不到 查父亲工厂
        displayContainsBean(beanFactory, "user");
        context.refresh();
        context.close();
    }
    public static BeanFactory createParent() {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
        reader.loadBeanDefinitions("beans.xml");
        return beanFactory;
    }
    public static void displayContainsBean(HierarchicalBeanFactory beanFactory  , String beanName) {
        boolean containsBean = containsBean(beanFactory, beanName);
        System.out.printf("当前工厂是否包含 %s",containsBean);
    }
    public static boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {
        BeanFactory parent = beanFactory.getParentBeanFactory();
        if (parent instanceof HierarchicalBeanFactory) {
            HierarchicalBeanFactory parentHierarchicalBeanFactory = HierarchicalBeanFactory.class.cast(parent);
            if (containsBean(parentHierarchicalBeanFactory, beanName)) {
                return true;
            };
        }
        return beanFactory.containsBean(beanName);
    }
    public static void disPlayLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {
        System.out.printf("当前工厂是否包含 %s", beanFactory.containsLocalBean(beanName));
        System.out.println();
    }
}
  • 延迟查找
    主要涉及 ObjectFactory 和 ObjectProvider
public class Client {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context  = new AnnotationConfigApplicationContext();
        context.register(Client.class);
        context.refresh();
        lookupIfAvailable(context);
        context.close();
    }
    public static void lookupIfAvailable(ApplicationContext context) {
        ObjectProvider<User> beanProvider = context.getBeanProvider(User.class);
        User user = beanProvider.getIfAvailable(() -> User.createUser());
        System.out.println(user);
    }
}
  • 安全查找
    在这里插入图片描述
    也就是说单一查前两个会抛出异常,所以不安全,其它的方法获取Bean获取不到也不会抛出异常。
public class Client {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context  = new AnnotationConfigApplicationContext();
        context.register(Client.class);
        context.refresh();
        displayBeanFactoryGetBean(context);
    }
    /**
     * 会发生异常
     * @param beanFactory
     */
    public static void displayBeanFactoryGetBean(BeanFactory beanFactory) {
        try {
             beanFactory.getBean(User.class);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 内部依赖
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 依赖查找中的异常
    在这里插入图片描述
    参考资料:Spring核心编程思想。

相关推荐

  1. Spring 依赖查找知识点总结

    2024-05-13 04:24:05       38 阅读
  2. Spring 依赖注入

    2024-05-13 04:24:05       14 阅读
  3. Spring依赖注入

    2024-05-13 04:24:05       12 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-13 04:24:05       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-13 04:24:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-13 04:24:05       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-13 04:24:05       20 阅读

热门阅读

  1. 第1章 信息系统综合知识 1.4 IT战略

    2024-05-13 04:24:05       11 阅读
  2. HTML学习笔记汇总

    2024-05-13 04:24:05       17 阅读
  3. skynet - spinlock 简单的自旋锁

    2024-05-13 04:24:05       15 阅读
  4. 【C++风云录】跨界融合:纺织工程与材料科学

    2024-05-13 04:24:05       12 阅读
  5. Node 学习-1

    2024-05-13 04:24:05       12 阅读
  6. 高并发场景

    2024-05-13 04:24:05       9 阅读
  7. 理解Python的装饰器 decorator

    2024-05-13 04:24:05       11 阅读
  8. TypeScript常见面试题第七节

    2024-05-13 04:24:05       14 阅读
  9. ASP.NET Core中的依赖注入(DI)

    2024-05-13 04:24:05       9 阅读
  10. Python3 笔记:Python的函数

    2024-05-13 04:24:05       11 阅读