大白话讲明白 把bean对象纳入Spring容器的几种方式,着重讲@Import注解 今天来说一下java开发中把一个bean对象放入Spring容器有哪几种方式第一种是用xml的方式或者用controller、service、comfigiration等注解第二种是使用Bean注解第三种是使用Import注解。下面分别展开讲一下一、第一种是用xml的方式或者用注解用xml这种方式就是在Spring的xml配置文件里写对应bean标签的内容就行了xml这种方式可能以前用的多现在实际开发中基本很少用到而且也很简单所以就不展开说了然后就是使用controller、service、comfigiration这一类常见的注解来把你的bean对象纳入Spring容器来管理。这种方式应该是大家平常使用最多的具体做法就是在对应的类上加上 这些注解Spring启动的时候会自动的去扫描这些类然后根据注解去解析并封装bean的定义信息封装成对应的BeanDefinition对象再用BeanDefinitionRegistry把对应的BeanDefinition注册到Spring中来然后再用反射生成对应的bean对象最后把bean对象放到Spring的一级缓存中也就是singletonObjectssingletonObjects它本质上其实就是个mapconcureentHashMap这些内容很多都和Spring的源码有关还有这个Spring的三级缓存这些后边有时间的话再单独写一下这里先不展开聊。反正总之第一种方式就是 在类上使用了controller、service、comfigiration等这些常用的注解后Spring启动的时候就会给加了这些注解的类生成bean对象然后纳入Spring管理。二、使用Bean注解第二种方式就是使用Bean注解来把一个bean交给Spring容器具体的使用方法如下Bean这种方式还可以跟Conditional这个注解配合来使用比如我有个多数据源的场景要求数据源1 不存在的话数据源2才交给Spring去生成类似这种场景就可以使用Bean 配合 Conditional 来实现具体操作如下先建一个DataSource 的类然后写一个类 实现 Condition 接口Condition这个接口非常简单里边就一个matches方法它的返回值是boolean 类型的。把你需要的判断逻辑写到这个方法里只有当这个方法返回true时使用Condition 注解的的这个bean才会被Spring加载并实例化。下面我写的 matches 这个方法实现的逻辑也非常简单就是数据源1不存在才会返回true接着使用刚才定义的 Condition 类最后测试验证一下如下图先把数据源1打开然后写一个测试方法去执行上边的测试方法执行后的结果如下图发现 数据源2并没有被Spring实例化说明数据源1 存在时数据源2确实没被Spring实例化如下图再把数据源1 注释掉再来看执行结果发现确实是数据源1不存在时数据源2 被Spring实例化了三、使用Import注解第三种方式是用Import注解Import这种又可以分为三种方式一是 Import(Xxx.class)这种一次只能加入一个类。二是用ImportSelector它可以一次加入多个类虽然能一次加入多个类但这种方式它也只能简单的按照全类名去加入不能做一些复杂的逻辑判断。三是用ImportBeanDefinitionRegistrar它可以实现复杂的条件判断下面分别展开讲1、Import(Xxx.class)写个Animal 接口写个Dog类实现 Animal 接口然后使用 Import注解 把 Dog类纳入Spring管理最后测试验证一下这个测试方法很简单一看就能看懂第一个是输出所有纳入Spring容器管理的类第二个是根据Type 输出 纳入Spring容器管理的 Animal类看结果输出了Dog类说明使用Import(Dog.class) 这种方式把Dog类纳入到Spring中管理了2、使用ImportSelectorImportSelector这种方式它可以一次加入多个类。虽然能一次加入多个类但这种方式它也只能简单的按照全类名去加入不能做一些复杂的逻辑判断。操作起来也非常简单写一个类 实现ImportSelector接口就可以了下面来操作一下先写2个新的动物类实现Animal接口接着写一个类 实现ImportSelector接口实现里面的selectImports 方法然后使用ImportSelector最后看测试结果下图可以看到Panda和Tiger已经使用ImportSelector的方式纳入Spring管理了ImportSelector这种方式挺重要的SpringBoot自动装配的源码里就是使用ImportSelector这种方式去把从配置文件中读取进来的候选装配类列表里 过滤完后需要真正执行自动装配的类装配到Spring容器中的可以截图看下SpringBoot自动装配的源码看到没SpringBoot自动装配的源码里它也是写了一个类去实现ImportSelector接口里的selectImports这个方法。这里就先简单看一下ImportSelector在源码里大概是怎么实际应用的关于更详细的Spring和SpringBoot源码得用Debug打断点进去一步一步跟源码才能讲的比较明白Spring和SpringBoot源码断点起来一步步调试还是比较麻烦的所以这个得等有比较空闲的时间才能单独的来写一篇时间的原因今天就先不深入了。3、使用ImportBeanDefinitionRegistrarImportBeanDefinitionRegistrar这种方式呢它可以实现复杂的条件判断。操作起来也非常简单写一个类 实现ImportBeanDefinitionRegistrar接口这个接口里有个registerBeanDefinitions 方法这个方法的参数可以拿到BeanDefinitionRegistry也就是BeanDefinition的注册器前边也提到过这个注册器它的作用就是把bean的定义信息注册加入到Spring容器中。在registerBeanDefinitions 这个方法里可以写你具体的条件判断逻辑然后用这个注册器去把bean注册到Spring容器中来。下面写个例子来操作一下我写的这个例子也非常简单大概意思就是进行逻辑判断如果Spring中已经有 Cat和Dog类了我就用ImportBeanDefinitionRegistrar这种方式来给Spring注入一个Monkey类。首先新建一个 Monkey实现Animal接口接着写一个类实现ImportBeanDefinitionRegistrar接口并实现里边的registerBeanDefinitions方法这个方法里我写的逻辑也非常简单就是上边说的 如果Spring中已经有 Cat和Dog类了我就用ImportBeanDefinitionRegistrar这种方式来给Spring注入一个Monkey类。然后使用刚才写的ImportBeanDefinitionRegistrar实现类最后看测试结果下图可以看到Cat和Dog在Spring容器中都存在的话就把Monkey加入Spring容器。已经使用ImportBeanDefinitionRegistrar这种方式把Monkey纳入Spring管理了上边已经把 常用的把bean对象纳入Spring容器的几种方式都详细的讲完了其中 Import注解 的这种方式虽然实际写代码的过程中相对其他两种方式用的可能会少一些但是我认为 Import这种方式 非常非常非常重要你看SpringBoot的源码你就会发现SpringBoot源码中 大量的使用了Import 这种方式。只有真正搞懂了Import是干嘛用的才更容易理解看懂Spring的源码这些一点一滴的基础知识搞懂了以后再去看Spring源码会容易很多。一点小小的提示希望对你有用。ok今天就写这么多吧纯手敲 原创不易如果觉得对你有帮助可以关注一下打赏一下感谢