SpringIoc依赖查找-5

news/2024/5/20 9:44:01/文章来源:https://blog.csdn.net/zsx1314lovezyf/article/details/128013766

1. 依赖查找的今世前生: Spring IoC容器从Java标准中学到了什么?

  • 单一类型依赖查找

    • JNDI - javax.naming.Context#lookup(javax.naming.Name)

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vrzgmly7-1669257924074)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221122112306129.png)]

    • JavaBeans - java.beans.beancontext.BeanContext

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g1ER47wg-1669257924076)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221122112822387.png)]

  • 集合类型依赖查找

    • java.beans.beancontext.BeanContext

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DOUakDJL-1669257924076)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221122112827221.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BbGHg86B-1669257924076)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221122112849605.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XlcSZ6MM-1669257924077)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221122112904560.png)]

      集合查找方法

  • 层次性依赖查找

    • java.beans.beancontext.BeanContext

      这里要集合 Java Beans Api

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CP5sDgqD-1669257924077)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221122113537918.png)]

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vc6gDUz5-1669257924077)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221122113631987.png)]

2. 单一类型依赖查找: 如何查找已知名称或类型的Bean对象?

  • 单一类型依赖查找接口- BeanFactory

    • 根据Bean名称查找

      • getBean(String)

      • Spring 2.5覆盖默认参数:getBean(String,Object…)

    • 根据 Bean类型查找

      • Bean实时查找

        • Spring 3.0 getBean(Class)

        • Spring 4.1覆盖默认参数:getBean(Class,Object…)

          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JlGW4QZa-1669257924078)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123110444600.png)]

          返回一个实例, 这个实例可能是shared(单例)可能是independent(原生), 这里就会告诉你一个不好的特点, 如果是shared的话, 当你的整个一个BeanFactory实例里面, 这个容器里面包含了同样一个实例, 那么之后你每次调用一次就会覆盖它的方法, 这个方式实际上有点不可取的, 那么因此建议采用 BeanFactory 的方式只好是只读方法, 要不你就完全的覆盖相关定义, 比如说你吧以前的BeanDefinition把它进行删除, 后面做一个Override做一个覆盖

    • Spring 5.1 Bean延迟查找

      • pom.xml

        <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.2.RELEASE</version></dependency>
        
      • getBeanProvider(Class)

        package org.xiaoge.thinking.in.spring.dependency.lookup;import org.springframework.beans.factory.ObjectProvider;
        import org.springframework.context.annotation.AnnotationConfigApplicationContext;
        import org.springframework.context.annotation.Bean;/*** * 通过{@link ObjectProvider} 进行依赖查找* * @PACKAGE_NAME: org.xiaoge.thinking.in.spring.dependency.lookup* @Classname ObjectProviderDemo* @Date 2022/11/23 11:23* @Author zhangxiao* @Description TODO*/
        public class ObjectProviderDemo {  // @Configuration 是非必须注解public static void main(String[] args) {// 创建 ApplicationContext 容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// 将当前类 ObjectProviderDemo 作为配置类 (Configuration class)applicationContext.register(ObjectProviderDemo.class);// 启动应用上下文applicationContext.refresh();// 依赖查找集合对象lookupByObjectProvider(applicationContext);// 关闭应用上下文applicationContext.close();}@Beanpublic String helloWord() { // @Bean没有value的时候 方法名称就是 Bean 名称 == "helloWord"return "hello word";}private static void lookupByObjectProvider(AnnotationConfigApplicationContext applicationContext) {// 通常来说String类型的Bean Spring 上下文是不会定义的, 因此这个时候可以用 注意:只能查唯一Bean多个Bean会报错NoUniqueBeanDefinitionExceptionObjectProvider<String> beanProvider = applicationContext.getBeanProvider(String.class);System.out.println(beanProvider.getObject());}}// 运行结果
        hello word
        
      • getBeanProvider(ResolvableType)

        后面写

    • 根据Bean名称+类型查找: getBean(String,Class)

    • 建议: 不要用覆盖默认参数的形式去查找

3. 集合类型依赖查找: 如何查找已知类型多个Bean集合?

  • 集合类型依赖查找接口- ListableBeanFactory

    • 根据Bean类型查找

      • 获取同类型Bean名称列表

        • getBeanNamesForType(Class)

          • 注意: 这个方法比较BeanDefinition里面的getBeanClassName和FactoryBean里面的getObjectType类型的匹配情况, 所以这个时候还没有涉及到Bean的初始化

            [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nCOG5tTX-1669257924078)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123133546661.png)]

        • Spring 4.2 getBeanNamesForType(ResolvableType)

      • 获取同类型Bean 实例列表

        • getBeansOfType(Class)以及重载方法
          • 注意: 它会涉及到Bean的初始化, 这个方法可能 会提前把一些你的类进行初始化, 初始化之后会导致一些Bean初始化并不完全, 这个时候会导致一些位置的错误, 所以在判断的时候首先去通过名称去判断, 然后再去通过类型判断, 这样的话比较好一点
    • 通过注解类型查找

      • 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>)

4. 层次性依赖查找: 依赖查找也有双亲委派?

  • 层次性依赖查找接口– HierarchicalBeanFactory

    • 双亲BeanFactory: getParentBeanFactory()

    • 层次性查找

      • 根据 Bean名称查找

        • 基于containsLocalBean方法实现

          package org.xiaoge.thinking.in.spring.dependency.lookup;import org.springframework.beans.factory.BeanFactory;
          import org.springframework.beans.factory.HierarchicalBeanFactory;
          import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
          import org.springframework.beans.factory.support.DefaultListableBeanFactory;
          import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
          import org.springframework.context.annotation.AnnotationConfigApplicationContext;
          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Configuration;/**** 层次性 依赖查找 示例** @PACKAGE_NAME: org.xiaoge.thinking.in.spring.dependency.lookup* @Classname HierarchicalDependencyLookupDemo* @Date 2022/11/23 13:52* @Author zhangxiao* @Description TODO*/
          public class HierarchicalDependencyLookupDemo {public static void main(String[] args) {// 创建 ApplicationContext 容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// 讲当前类 HierarchicalDependencyLookupDemo 作为配置类 (Configuration Class)applicationContext.register(HierarchicalDependencyLookupDemo.class);// 1. 获取HierarchicalBeanFactory <- ConfigurableBeanFactory <- ConfigurableListableBeanFactoryConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();System.out.println("当前 BeanFactory 的 Parent BeanFactory : " + beanFactory.getParentBeanFactory());ConfigurableListableBeanFactory parentBeanFactory = createParentBeanFactory();// 2. 设置 Parent BeanFactorybeanFactory.setParentBeanFactory(parentBeanFactory);System.out.println("当前 BeanFactory 的 Parent BeanFactory : " + beanFactory.getParentBeanFactory());// 启动应用上下文applicationContext.refresh();// 当前 Bean 是否在当前容器中displayContainsLocalBean(beanFactory, "user");displayContainsLocalBean(parentBeanFactory, "user");// 当前 Bean 是否在容器中 实现双亲委派displayContainsBean(beanFactory, "user");displayContainsBean(parentBeanFactory, "user");// 关闭应用上下文applicationContext.close();}/*** 查询 Bean 是否 在容器中 实现双亲委派* @param beanFactory* @param beanName*/private static void displayContainsBean(HierarchicalBeanFactory beanFactory, String beanName) {System.out.printf("当前 BeanFactory[%s] 是否包含 Bean[name : %s] : %s\n", beanFactory, beanName, containsBean(beanFactory, beanName));}/*** 递归实现, 查找 Bean 这是 BeanFactoryUtils 没有实现的* @param beanFactory* @param beanName* @return*/private static Boolean containsBean(HierarchicalBeanFactory beanFactory, String beanName) {if (beanFactory.containsLocalBean(beanName)) {return true;}// 获取父容器BeanFactory parentBeanFactory = beanFactory.getParentBeanFactory();// 判断了类型也判断了它是否为空if (parentBeanFactory instanceof HierarchicalBeanFactory) {// 转换类型HierarchicalBeanFactory parentHierarchicalBeanFactory = HierarchicalBeanFactory.class.cast(parentBeanFactory);if (parentHierarchicalBeanFactory.containsLocalBean(beanName)) {return true;}containsBean(parentHierarchicalBeanFactory, beanName);}return false;}/*** 当前 bean 是否在 当前备本地(它自己的容器)容器中* @param beanFactory* @param beanName*/private static void displayContainsLocalBean(HierarchicalBeanFactory beanFactory, String beanName) {System.out.printf("当前 BeanFactory[%s] 是否包含 Local Bean[name : %s] : %s\n", beanFactory, beanName, beanFactory.containsLocalBean(beanName));}/**** @return*/private static ConfigurableListableBeanFactory createParentBeanFactory() {// 创建BeanFactory容器DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);// XML 配置文件 ClassPath 路径String location = "classpath:META-INF/dependency-lookup-context.xml";// 加载配置reader.loadBeanDefinitions(location);return beanFactory;}}// 运行结果
          当前 BeanFactoryParent BeanFactory : null
          当前 BeanFactoryParent BeanFactory : org.springframework.beans.factory.support.DefaultListableBeanFactory@3c09711b: defining beans [user,objectFactory,superUser]; root of factory hierarchy
          当前 BeanFactory[org.springframework.beans.factory.support.DefaultListableBeanFactory@1e397ed7: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,hierarchicalDependencyLookupDemo]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@3c09711b] 是否包含 Local Bean[name : user] : false
          当前 BeanFactory[org.springframework.beans.factory.support.DefaultListableBeanFactory@3c09711b: defining beans [user,objectFactory,superUser]; root of factory hierarchy] 是否包含 Local Bean[name : user] : true
          当前 BeanFactory[org.springframework.beans.factory.support.DefaultListableBeanFactory@1e397ed7: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,hierarchicalDependencyLookupDemo]; parent: org.springframework.beans.factory.support.DefaultListableBeanFactory@3c09711b] 是否包含 Bean[name : user] : true
          当前 BeanFactory[org.springframework.beans.factory.support.DefaultListableBeanFactory@3c09711b: defining beans [user,objectFactory,superUser]; root of factory hierarchy] 是否包含 Bean[name : user] : true
      • 根据 Bean类型查找实例列表

        • 单一类型: BeanFactoryUtils#beanOfType

        • 集合类型:BeanFactoryUtils#beansOfTypeIncludingAncestors

          • 注意: 改方法实现了双亲委派的原则

            [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uhtppiEk-1669257924079)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123151054825.png)]

      • 根据Java 注解查找名称列表

        • BeanFactoryUtils#beanNamesForTypeIncludingAncestors

5. 延迟依赖查找: 非延迟初始化Bean也能实现延迟查找?

  • Bean延迟依赖查找接口

    • org. springframework. beans.factory.ObjectFactory

    • org. springframework. beans.factory.ObjectProvider

      • Spring 5 对Java 8 特性扩展

        • 函数式接口

          • getIfAvailable (Supplier)
          • ifAvailable (Consumer)
        • Stream扩展- stream ()

          package org.xiaoge.thinking.in.spring.dependency.lookup;import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
          import org.springframework.beans.factory.ObjectProvider;
          import org.springframework.context.annotation.AnnotationConfigApplicationContext;
          import org.springframework.context.annotation.Bean;
          import org.springframework.context.annotation.Primary;
          import org.xiaoge.thinking.in.spring.ioc.overview.domain.User;/**** 通过{@link ObjectProvider} 进行依赖查找** @PACKAGE_NAME: org.xiaoge.thinking.in.spring.dependency.lookup* @Classname ObjectProviderDemo* @Date 2022/11/23 11:23* @Author zhangxiao* @Description TODO*/
          public class ObjectProviderDemo {  // @Configuration 是非必须注解public static void main(String[] args) {// 创建 ApplicationContext 容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// 将当前类 ObjectProviderDemo 作为配置类 (Configuration class)applicationContext.register(ObjectProviderDemo.class);// 启动应用上下文applicationContext.refresh();// 延迟加载依赖查找集合对象lookupByObjectProvider(applicationContext);// 延迟加载lookupIfAvailable(applicationContext);// 延迟加载(查找的是集合)lookupByStreamOps(applicationContext);// 关闭应用上下文applicationContext.close();}private static void lookupByStreamOps(AnnotationConfigApplicationContext applicationContext) {ObjectProvider<String> beanProvider = applicationContext.getBeanProvider(String.class);
          //        Iterable<String> stringIterable = beanProvider;
          //        for (String s : stringIterable) {
          //            System.out.println(s);
          //        }// Stream -> Method referencebeanProvider.stream().forEach(System.out::println);}/*** 这是个兜底方案, 当没有User Bean 不在容器中时  使用 自己的* @param applicationContext*/private static void lookupIfAvailable(AnnotationConfigApplicationContext applicationContext) {ObjectProvider<User> beanProvider = applicationContext.getBeanProvider(User.class);User user = beanProvider.getIfAvailable(User::createUser);System.out.println("当前 User 对象 : " + user);}@Bean@Primarypublic String helloWord() { // @Bean没有value的时候 方法名称就是 Bean 名称 == "helloWord"return "hello word";}@Beanpublic String message() { // @Bean没有value的时候 方法名称就是 Bean 名称 == "helloWord"return "message";}private static void lookupByObjectProvider(AnnotationConfigApplicationContext applicationContext) {// 通常来说String类型的Bean Spring 上下文是不会定义的, 因此这个时候可以用 注意:只能查唯一Bean多个Bean会报错NoUniqueBeanDefinitionExceptionObjectProvider<String> beanProvider = applicationContext.getBeanProvider(String.class);System.out.println(beanProvider.getObject());}}// 运行结果
          hello word
          当前 User 对象 : User{id=1, name='xiaoge'}
          hello word
          message
          

6. 安全依赖查找

  • 依赖查找安全性对比

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qU0KbAWg-1669257924079)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123154119989.png)]

    注意:层次性依赖查找的安全性取决于其扩展的单一或集合类型的 BeanFactory 接口

    package org.xiaoge.thinking.in.spring.dependency.lookup;import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.ListableBeanFactory;
    import org.springframework.beans.factory.ObjectFactory;
    import org.springframework.beans.factory.ObjectProvider;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.xiaoge.thinking.in.spring.ioc.overview.domain.User;/*** 类型安全 依赖查找 示例** @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>* @since*/
    public class TypeSafetyDependencyLookupDemo {public static void main(String[] args) {// 创建 ApplicationContext 容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// 将当前类 TypeSafetyDependencyLookupDemo 作为配置类 (Configuration class)applicationContext.register(TypeSafetyDependencyLookupDemo.class);// 启动应用上下文applicationContext.refresh();// 演示 BeanFactory#getBean 方法的安全性displayBeanFactoryGetBean(applicationContext);// 演示 ObjectFactory#getObject 方法的安全性displayObjectFactoryGetObject(applicationContext);// 演示 ObjectProvider#ifAvailable 方法的安全性displayObjectProviderIfAvailable(applicationContext) ;// 演示 ListableBeanFactory#getBeansOfType 方法的安全性displayListableBeanFactoryGetBeansOfType(applicationContext);// 演示 ObjectProvider Stream 操作的安全性displayObjectProviderStreamOps(applicationContext);// 关闭应用上下文applicationContext.close();}/*** ObjectProvider* @param applicationContext*/private static void displayObjectProviderStreamOps(AnnotationConfigApplicationContext applicationContext) {ObjectProvider<User> objectProvider = applicationContext.getBeanProvider(User.class);printBeansException("displayObjectProviderStreamOps", () -> objectProvider.forEach(System.out::println));}/*** ListableBeanFactory#getBeansOfType 是否安全* @param beanFactory*/private static void displayListableBeanFactoryGetBeansOfType(ListableBeanFactory beanFactory) {printBeansException("displayListableBeanFactoryGetBeansOfType", () -> beanFactory.getBeansOfType(User.class));}/*** ObjectProvider#getIfAvailable 是否安全* @param applicationContext*/private static void displayObjectProviderIfAvailable(AnnotationConfigApplicationContext applicationContext) {ObjectProvider<User> objectProvider = applicationContext.getBeanProvider(User.class);printBeansException("displayObjectProviderIfAvailable", () -> objectProvider.getIfAvailable());}/*** ObjectFactory#getObject 是否安全* @param applicationContext*/private static void displayObjectFactoryGetObject(AnnotationConfigApplicationContext applicationContext) {// ObjectProvider is ObjectFactoryObjectFactory<User> objectFactory = applicationContext.getBeanProvider(User.class);printBeansException("displayObjectFactoryGetObject", () -> objectFactory.getObject());}/*** BeanFactory#getBean 是否安全* @param applicationContext*/private static void displayBeanFactoryGetBean(AnnotationConfigApplicationContext applicationContext) {printBeansException("displayBeanFactoryGetBean", () -> applicationContext.getBean(User.class));}/*** 打印异常信息* @param source* @param runnable*/private static void printBeansException(String source, Runnable runnable) {System.err.println("===========================================");System.err.println("Source from : " + source);try {runnable.run();} catch (BeansException e) {e.printStackTrace();}}}// 运行结果
    ===========================================
    Source from : displayBeanFactoryGetBean
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.xiaoge.thinking.in.spring.ioc.overview.domain.User' availableat org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1126)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.lambda$displayBeanFactoryGetBean$4(TypeSafetyDependencyLookupDemo.java:90)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.printBeansException(TypeSafetyDependencyLookupDemo.java:103)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.displayBeanFactoryGetBean(TypeSafetyDependencyLookupDemo.java:90)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.main(TypeSafetyDependencyLookupDemo.java:30)
    ===========================================
    Source from : displayObjectFactoryGetObject
    org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.xiaoge.thinking.in.spring.ioc.overview.domain.User' availableat org.springframework.beans.factory.support.DefaultListableBeanFactory$1.getObject(DefaultListableBeanFactory.java:370)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.lambda$displayObjectFactoryGetObject$3(TypeSafetyDependencyLookupDemo.java:82)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.printBeansException(TypeSafetyDependencyLookupDemo.java:103)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.displayObjectFactoryGetObject(TypeSafetyDependencyLookupDemo.java:82)at org.xiaoge.thinking.in.spring.dependency.lookup.TypeSafetyDependencyLookupDemo.main(TypeSafetyDependencyLookupDemo.java:33)
    ===========================================
    Source from : displayObjectProviderIfAvailable
    ===========================================
    Source from : displayListableBeanFactoryGetBeansOfType
    ===========================================
    Source from : displayObjectProviderStreamOps
    

    由此可见建议使用ObjectProvider来进行依赖查找

7. 内建可查找的依赖: 那些Spring IoC容器内建依赖可供查找?

  • AbstractApplicationContext 内建可查找的依赖

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9kofvJzg-1669257924080)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123164247234.png)]

  • 注解驱动Spring 应用上下文内建可查找的依赖(部分)

    C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123164332343.png

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tiJRKs5K-1669257924081)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123164505327.png)]

    其实也非常好记, 只需要关注AnnotationConfigUtils就知道了

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jktjKKOn-1669257924081)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123170438893.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PidXZteP-1669257924082)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123170557025.png)]

8. 依赖查找中的经典异常: Bean找不到?Bean不唯一的?Bean创建失败?

  • BeansException子类型

    C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221123170857785.png

  • NoSuchBeanDefinitionException不做演示, 上面案例有

  • NoUniqueBeanDefinitionException

    package org.xiaoge.thinking.in.spring.dependency.lookup;import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;/*** {@link NoUniqueBeanDefinitionException} 示例代码** @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>* @since*/
    public class NoUniqueBeanDefinitionExceptionDemo {public static void main(String[] args) {// 创建 ApplicationContext 容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// 将当前类 NoUniqueBeanDefinitionExceptionDemo 作为配置类 (Configuration class)applicationContext.register(NoUniqueBeanDefinitionExceptionDemo.class);// 启动应用上下文applicationContext.refresh();// 由于 Spring 上下文存在两个String类型的 Bean, 通过单一类型查找会报错try {applicationContext.getBean(String.class);} catch (NoUniqueBeanDefinitionException e) {System.err.printf("Spring 应用上下文存在%d个 %s 类型的Bean, 具体原因: %s",e.getNumberOfBeansFound(),String.class.getName(),e.getMessage());}// 关闭应用上下文applicationContext.close();}@Beanpublic String bean1() {return "bean1";}@Beanpublic String bean2() {return "bean2";}
    }// 运行结果
    Spring 应用上下文存在2java.lang.String 类型的Bean, 具体原因: No qualifying bean of type 'java.lang.String' available: expected single matching bean but found 2: bean1,bean2
  • BeanInstantiationException

    package org.xiaoge.thinking.in.spring.dependency.lookup;import org.springframework.beans.BeanInstantiationException;
    import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
    import org.springframework.beans.factory.config.BeanDefinition;
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;/*** {@link BeanInstantiationException} 示例** @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>* @since*/
    public class BeanInstantiationExceptionDemo {public static void main(String[] args) {// 创建 ApplicationContext 容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// 注册 BeanDefinition Bean Class 是一个 CharSequence 接口BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CharSequence.class);// 注册BeanapplicationContext.registerBeanDefinition("errorBean", beanDefinitionBuilder.getBeanDefinition());// 启动应用上下文applicationContext.refresh();// 关闭应用上下文applicationContext.close();}}// 运行结果
    十一月 23, 2022 5:56:42 下午 org.springframework.context.support.AbstractApplicationContext refresh
    警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'errorBean': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.lang.CharSequence]: Specified class is an interface
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'errorBean': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.lang.CharSequence]: Specified class is an interfaceat org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1320)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1214)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)at org.xiaoge.thinking.in.spring.dependency.lookup.BeanInstantiationExceptionDemo.main(BeanInstantiationExceptionDemo.java:28)
    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [java.lang.CharSequence]: Specified class is an interfaceat org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:70)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1312)... 11 moreProcess finished with exit code 1
  • BeanCreationException

    package org.xiaoge.thinking.in.spring.dependency.lookup;import org.springframework.beans.factory.BeanCreationException;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;import javax.annotation.PostConstruct;/*** {@link BeanCreationException} 示例** @author <a href="mailto:1330137071@qq.com">Zhang Xiao</a>* @since*/
    public class BeanCreationExceptionDemo {public static void main(String[] args) {// 创建 ApplicationContext 容器AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();// 注册 BeanDefinition Bean Class 是一个 POJO 普通类,不过初始化方法回调时抛出异常BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(POJO.class);// 注册BeanapplicationContext.registerBeanDefinition("errorBean", beanDefinitionBuilder.getBeanDefinition());// 启动应用上下文applicationContext.refresh();// 关闭应用上下文applicationContext.close();}static class POJO implements InitializingBean {@PostConstruct // CommonAnnotationBeanPostProcessor 实现的这个注解, 顺序很重要, 因为PostConstruct注解装饰的方法会先执行public void init() throws Exception {throw new Exception("init() : For purposes...");}@Overridepublic void afterPropertiesSet() throws Exception {throw new Exception("afterPropertiesSet() : For purposes...");}}}// 运行结果
    十一月 23, 2022 5:57:12 下午 org.springframework.context.support.AbstractApplicationContext refresh
    警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'errorBean': Invocation of init method failed; nested exception is java.lang.Exception: init() : For purposes...
    Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'errorBean': Invocation of init method failed; nested exception is java.lang.Exception: init() : For purposes...at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:416)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:879)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)at org.xiaoge.thinking.in.spring.dependency.lookup.BeanCreationExceptionDemo.main(BeanCreationExceptionDemo.java:28)
    Caused by: java.lang.Exception: init() : For purposes...at org.xiaoge.thinking.in.spring.dependency.lookup.BeanCreationExceptionDemo$POJO.init(BeanCreationExceptionDemo.java:38)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389)at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333)at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157)... 12 moreProcess finished with exit code 1

9. 面试题精选

  • ObjectFactory 与BeanFactory 的区别?

    答: 0bjectFactory 与 BeanFactory 均提供依赖查找的能力。

    不过 ObjectFactory 仅关注一个 或一种类型的 Bean 依赖查找, 并且自身不具备依赖查找的能力,能力则由 BeanFactory 输出。

    BeanFactory则提供了单一类型、集合类型以及层次性等多种依赖查找方式。

    根据名称查找

    C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221124100431367.png

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8nJA3QGQ-1669257924083)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221124100527299.png)]

    C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221124100618961.png

    根据类型查找

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-89L10AE8-1669257924084)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221124102640878.png)]

    C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221124102627020.png

    C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221124102750503.png

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-713k2XRX-1669257924085)(C:\Users\13301\AppData\Roaming\Typora\typora-user-images\image-20221124102926690.png)]

    最终还是用了BeanFactory

    可以通过改文章, 可以看出它是怎么通过ObjectFactoryCreatingFactoryBean创建ObjectFactory的

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_224871.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

sqli-labs/Less-51

这一关的欢迎界面依然是以sort作为注入点 我们首先来判断一下是否为数字型注入 输入如下 sortrand() 对尝试几次 发现页面并没有发生变化 说明这道题的注入类型属于字符型 然后尝试输入以下内容 sort1 报错了 报错信息如下 我们从报错信息可以知道这道题的注入类型属于单…

期末前端web大作业——HTML+CSS+JavaScript仿京东购物商城网页制作(7页)

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

#边学边考 必修5 高项:对人管理 第2章 项目沟通管理和干系人管理

答题报告 自我分析 有可能是间隔时间太长&#xff0c;本章节从开始学习到今天&#xff08;11.24&#xff09;学完&#xff0c;中间至少停止了1周以上&#xff0c;造成对基本知识记忆不牢固。对重点知识没有重点记忆&#xff0c;走马观花&#xff0c;以至于混淆。 答题解析 关…

MySQL 进阶 图文详解InnoDB储存引擎

前言 SQL 语句的最终执行者是存储引擎。存储引擎在经解析器、优化器处理后被执行器调用其接口执行优化后的执行计划。MySQL 存储引擎包括 InnoDB、Myisam、Memory、Archive、CSV 存储引擎等&#xff0c;其中最常用也是MySQL 默认的存储引擎是 InnoDB。 写入缓冲池&#xff08;…

用DIV+CSS技术设计的水果介绍网站(web前端网页制作课作业)

&#x1f380; 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

软件测试面试技巧有哪些?可以从这2个方面去进行准备

面试所有只职场人&#xff0c;通往工作岗位的第一道关卡&#xff0c;也是最重要的一道门槛。而面试中&#xff0c;如何回答HR提出的问题很大程度上决定了面试能不能成功。所以这些软件测试的面试技巧你可不能错过了。 首先是自我介绍 自我介绍的时间不能太短&#xff0c;几十秒…

(附源码)计算机毕业设计JavaJava毕设项目财务管理系统的设计与实现

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven Vue 等等组成&#xff0c;B/…

【Flutter】shape 属性 ShapeBorder,形状

文章目录前言一、shape 是什么&#xff1f;二、不同的形状1.BeveledRectangleBorder2.Border3.CircleBorder圆形4.ContinuousRectangleBorder连续圆角5.StadiumBorder 体育场边界 &#xff0c;药丸形状6.OutlineInputBorder外边框可以定制圆角7.UnderlineInputBorder下划线总结…

Springboot Security 前后端分离模式自由接口最小工作模型

但凡讲解Springboot Security的教程&#xff0c;都是根据其本身的定义&#xff0c;前后端整合在一起&#xff0c;登录采用form或者basic。我们现在的很多项目&#xff0c;前后端分离&#xff0c;form登录已经不适用了。很多程序的架构要求所有的接口都采用application/json方式…

复制集群架构设计技巧

Redis Sentinel设计技巧 Redis Sentinel基本架构 Monitoring Sentinel可以监控Redis节点的状态 Notification Sentinel可以通过API进行集群状态通知 Automatic failover Sentinel实现故障自动切换 Configuration provider Sentinel为client提供发现master节点的发现功能…

Java项目:JSP校园运动会管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目包含三种角色&#xff1a;运动员、裁判员、管理员&#xff1b; 运动员角色包含以下功能&#xff1a; 运动员登录,个人信息修改,运动成绩…

【优化求解】粒子群算法求解干扰受限无人机辅助网络优化问题【含Matlab源码 230期】

⛄一、粒子群简介 1 粒子群优化算法 粒子群优化算法( PSO)是指通过模拟鸟群觅食的协作行为,实现群体最优化。PSO是一种并行计算的智能算法,其基本模型如下: 假设群体规模为M,在D维空间中,群体中的第i个个体表示为XD ( xm1,xm2…xm D)T,速度表示为VD ( vm1,vm2…vm D)T,位置( …

一个简单的音乐网站设计与实现(HTML+CSS)

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 音乐网页设计 | 仿网易云音乐 | 各大音乐官网网页 | 明星音乐演唱会主题 | 爵士乐音乐 | 民族音乐 | 等网站的设计与制作 | HTML期末大学生网页设计作…

【生成模型】Diffusion Models:概率扩散模型

---前言一、Diffusion Model 基本介绍二、生成模型对比三、直观理解Diffusion model四、形式化解析Diffusion model五、详解 Diffusion Model&#xff08;数学推导&#xff09;1.前向过程(扩散过程)2.逆扩散过程3.逆扩散条件概率推导4.训练损失六、训练、测试伪代码1. 训练2.测…

大一学生WEB前端静态网页——旅游网页设计与实现-张家口 6页

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 游景点介绍 | 旅游风景区 | 家乡介绍 | 等网站的设计与制作| HTML期末大学生网页设计作业 HTML&#xff1a;结构 CSS&#xff1a;样式 在操作方面上运…

string类(一)

目录 一、 string类对象的常见构造 二、string类对象的容量操作 2.1 size(返回字符串有效字符长度) 2.2 capacity(返回空间总大小) 2.3 reserve扩空间​编辑 2.4 resize初始化不会覆盖本来的空间​编辑 2.5 对于test_string7中每一句代码进行调试运行 三、string类对象的…

如何给PDF解密?建议收藏这些方法

我们在传输接收文件的时候&#xff0c;经常都是以PDF格式进行的&#xff0c;因为PDF格式具有很强的稳定性。那小伙伴们平时接收的时候&#xff0c;会不会发现有些PDF文件为了保密性会进行加密&#xff0c;如果我们经常需要使用它&#xff0c;就需要不断地输入密码&#xff0c;这…

ISCSLP 2022 | NPU-ASLP实验室8篇论文被录用

作为语音处理技术领域的旗舰国际会议&#xff0c;ISCSLP2022&#xff08;International Symposium on Chinese Spoken Language Processing&#xff09;将于12月11-14日在新加坡举办。 西工大音频语音与语言处理研究组(ASLPNPU)本届会议将携合作伙伴宣读论文8篇&#xff0c;涉…

计算机网络复习——第六章网络层

hhhhh 还是今天的我&#xff0c;今天把这两个肝了&#xff0c;准备27考试&#xff0c;耶耶耶&#xff01;&#xff01;&#xff01;小h加油&#xff01; 《计算机网络》&#xff08;谢希仁&#xff09;内容总结 (javaguide.cn) 重点知识&#xff1a; 域名系统&#xff08;DN…

关于web前端大作业的HTML网页设计——我的班级网页HTML+CSS+JavaScript

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…