Spring依赖查找(二)

延迟依赖查找
Bean延迟依赖查找接口

  • org.springframework.beans.factory.ObjectFactory
  • org.springframework.beans.factory.ObjectProvider
    • Spring 5对java 8特性扩展
      • 函数式接口
        • getIfAvailiable(Supplier)
        • IfAvaliable(Consumer)
      • Stream扩展-Stream()
        依赖查找安全性对比
        截屏2022-09-15 15.00.13.png

        注意:层次性依赖查找的安全性取决于其扩展的单一或集合类型的BeanFactory接口
        内建可查找的依赖
  • AbstractApplicationContext内建可查找的依赖
    截屏2022-09-15 16.29.53.png

    注解驱动Spring应用上下文内建可查找的依赖(部分)
    截屏2022-09-15 16.39.18.png

    截屏2022-09-15 21.58.14.png

    依赖查找中的经典异常
  • BeansException子类型


    截屏2022-09-16 10.11.46.png
public class NoUniqueBeanDefinitionExceptionDemo {
    public static void main(String[] args) {
        //创建BeanFactory容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //ObjectProviderDemo Class(配置类)
        applicationContext.register(NoUniqueBeanDefinitionExceptionDemo.class);
        //启动spring应用上下文
        applicationContext.refresh();
        try {
            applicationContext.getBean(String.class);
        } catch (NoUniqueBeanDefinitionException e){
            System.err.printf("Spring 应用上下文存在 %d 个 s% 类型的 Bean ,具体原因:%s%n",
                    e.getNumberOfBeansFound(),
                    String.class.getName(),
                    e.getMessage());
        }
        //显示的关闭spring应用上下文
        applicationContext.close();
    }

    @Bean
    public String bean1(){
        return "bean1";
    }

    @Bean
    public String bean2(){
        return "bean2";
    }

}

public class BeanInstanationExceptionDemo {
    public static void main(String[] args) {
        //创建BeanFactory容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册BeanDefinition Bean Class 是一个 CharSequence 接口
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CharSequence.class);
        applicationContext.registerBeanDefinition("errorBean",beanDefinitionBuilder.getBeanDefinition());
        //启动spring应用上下文
        applicationContext.refresh();
        //显示的关闭spring应用上下文
        applicationContext.close();
    }
}

public class BeanCreationExceptionDemo {
    public static void main(String[] args) {
        //创建BeanFactory容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //注册BeanDefinition Bean Class 是一个 POJO 普通类 ,不过初始化方法回调时抛出异常
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(POJO.class);
        applicationContext.registerBeanDefinition("errorBean",beanDefinitionBuilder.getBeanDefinition());
        //启动spring应用上下文
        applicationContext.refresh();
        //显示的关闭spring应用上下文
        applicationContext.close();
    }

    static class POJO implements InitializingBean {
        @PostConstruct // CommonAnnotationBeanProcessor
        public void init() throws Throwable{
            throw new Throwable("init() : For Purpose....");
        }
        public void afterPropertiesSet() throws Exception {
            throw new Exception("For purposes.....");
        }
    }
}

面试题
ObjectBeanFactory 与 BeanFactory 的区别?
答:ObjectBeanFactory 与 BeanFactory均提供依赖查找的能力。不过,ObjectBeanFactory仅关注一个或一种类型的Bean的依赖查找,并且自身不具备依赖查找的能力,能力由BeanFactory输出。BeanFactory提供l单一类型、集合类型及层次性等多种依赖查找的方式。
BeanFactory.getBean方法的执行是线程安全的吗?
答:BeanFactory.getBean方法的执行是线程安全,操作过程中会添加互斥锁。

你可能感兴趣的:(Spring依赖查找(二))