美文网首页
Spring Boot bean查找的多种方式

Spring Boot bean查找的多种方式

作者: 爱跳的老鼠君 | 来源:发表于2021-10-05 13:39 被阅读0次

    Spring boot中查找bean有多种方式,目前我了解到的有以下五种。按照返回结果来分类,可以分成查找单个bean和bean 集合两大类, 按照查找是否安全来分类, 可以分成安全查找和非安全查找。

    返回结果 是否安全 代码
    单个bean BeanFactory.getBean()
    单个bean ObjectProvider.getObject()
    单个bean ObjectProvider.getIfAvailable()
    集合bean ListableBeanFactory.getBeansOfType()
    集合bean ObjectProvider.stream

    下面将以上五种方式的代码呈现给大家

    1. BeanFactory.getBean 是最容易想到的一种查找bean的方式, 但是这种方式是非常不安全的。 如果没有找到符合要求的bean, 就会throw NoSuchBeanDefinitionException。 如果找到多个符合要求的bean, 就会throw NoUniqueBeanDefinitionException。
    private static void lookupByBeanFactoryGetBean(BeanFactory beanFactory) {
            commonRunLookupJob(() -> {
                beanFactory.getBean(String.class);
            });
        }
    private static void commonRunLookupJob(Runnable runnable) {
            try {
                runnable.run();
            } catch (BeansException exception) {
                exception.printStackTrace();
            }
        }
    }
    
    
    1. ObjectProvider.getObject。 ObjectProvider 是spring4.3开始新加的一个类, 继承自ObjectFactory。
    private static void lookupByObjectProviderGetObject(BeanFactory beanFactory) {
            ObjectProvider<String> beanProvider = beanFactory.getBeanProvider(String.class);
            commonRunLookupJob(() -> {
                beanProvider.getObject();
            });
        }
    

    3.ObjectProvider.getIfAvailable. 顾名思义, 就是如果有符合要求的bean的时候, 才会返回, 否则就返回null。 但是大家注意, 这个方法并不是说就不会throw BeansException了。 如果查找的是个lazy 初始化的bean,在调用这个方法的时候才会去create bean, 所以如果在create的时候就有问题, 还是会throw BeansException的。

    private static void lookupByObjectProviderGetIfAvailable(BeanFactory beanFactory) {
            ObjectProvider<String> beanProvider = beanFactory.getBeanProvider(String.class);
            commonRunLookupJob(() -> {
                beanProvider.getIfAvailable();
            });
        }
    
    1. ListableBeanFactory.getBeansOfType 返回的是一个以bean 名字作为key的Map
    private static void lookupByListableBeanFactoryGetBeansOfType(ListableBeanFactory beanFactory) {
    
            commonRunLookupJob(() -> {
                beanFactory.getBeansOfType(String.class);
            });
        }
    
    1. BeanProvider 同时也继承自Iterable 接口, 所以也支持stream。
    private static void lookupByObjectProviderStream(BeanFactory beanFactory) {
            ObjectProvider<String> beanProvider = beanFactory.getBeanProvider(String.class);
            commonRunLookupJob(() -> {
                beanProvider.stream().forEach(System.out::println);
            });
        }
    

    以下附录是完整的demo 代码

    package com.matthew.bayi.lookup;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.BeanFactory;
    import org.springframework.beans.factory.ListableBeanFactory;
    import org.springframework.beans.factory.ObjectProvider;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Lazy;
    
    public class BeanLookupDemo {
    
    
        public static void main(String[] args) {
            // create application context
            AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    
            // register configuration class
            applicationContext.register(BeanLookupDemo.class);
    
            // start application context
            applicationContext.refresh();
    
            // loop up by beanfactory getbean
            lookupByBeanFactoryGetBean(applicationContext);
    
            // loop up by ObjectProvider GetObject
            lookupByObjectProviderGetObject(applicationContext);
    
            // loop up by ObjectProvider getIfAvailable
            lookupByObjectProviderGetIfAvailable(applicationContext);
    
            // look up by ListableBeanFactory GetBeansOfType
            lookupByListableBeanFactoryGetBeansOfType(applicationContext);
    
            // look up by ObjectProvider Stream
            lookupByObjectProviderStream(applicationContext);
    
            // close application context
            applicationContext.close();
    
        }
    
        @Bean
        @Lazy
        String helloWorld(){
    //        throw new RuntimeException("Error Create bean");
            return "Hello";
        }
    
    
        private static void lookupByBeanFactoryGetBean(BeanFactory beanFactory) {
            commonRunLookupJob(() -> {
                beanFactory.getBean(String.class);
            });
        }
    
        private static void lookupByObjectProviderGetObject(BeanFactory beanFactory) {
            ObjectProvider<String> beanProvider = beanFactory.getBeanProvider(String.class);
            commonRunLookupJob(() -> {
                beanProvider.getObject();
            });
        }
    
        private static void lookupByObjectProviderGetIfAvailable(BeanFactory beanFactory) {
            ObjectProvider<String> beanProvider = beanFactory.getBeanProvider(String.class);
            commonRunLookupJob(() -> {
                beanProvider.getIfAvailable();
            });
        }
    
        private static void lookupByListableBeanFactoryGetBeansOfType(ListableBeanFactory beanFactory) {
    
            commonRunLookupJob(() -> {
                beanFactory.getBeansOfType(String.class);
            });
        }
    
        private static void lookupByObjectProviderStream(BeanFactory beanFactory) {
            ObjectProvider<String> beanProvider = beanFactory.getBeanProvider(String.class);
            commonRunLookupJob(() -> {
                beanProvider.stream().forEach(System.out::println);
            });
        }
    
        private static void commonRunLookupJob(Runnable runnable) {
            try {
                runnable.run();
            } catch (BeansException exception) {
                exception.printStackTrace();
            }
        }
    
    }
    
    

    相关文章

      网友评论

          本文标题:Spring Boot bean查找的多种方式

          本文链接:https://www.haomeiwen.com/subject/jvhgnltx.html