当前位置:首页 > 编程笔记 > 正文
已解决

由浅入深,详细总结 Spring 八种加载 Bean 的方式

来自网友在路上 177877提问 提问时间:2023-10-26 20:31:08阅读次数: 77

最佳答案 问答题库778位专家为你答疑解惑

文章目录

  • 方式一:XML 方式声明 bean
  • 方式二:XML + 注解方式声明 bean
  • 方式三:注解方式声明配置类
    • 扩展一:@Bean 返回的对象和真实 Bean 对象可能不是一个
    • 扩展二:加载配置类的同时,加载配置文件(系统迁移)
    • 扩展三:@ImportResource、@Bean、@Component 加载优先级
    • 扩展四:@ImportResource 引入多个配置文件的优先级
    • 扩展五:proxyBeanMethods=true 生成代理对象
  • 方式四:@Import 注解注入
  • 方式五:上下文对象在容器初始化完毕后注入
  • 方式六:实现 ImportSelector 接口 ★
  • 方式七:实现 ImportBeanDefinitionRegistrar 接口 ★
  • 方式八:实现 BeanDefinitionRegistryPostProcessor 接口


方式一:XML 方式声明 bean

目录初始化:
在这里插入图片描述

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.axy</groupId><artifactId>springboot_bean_init</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.9</version></dependency></dependencies>
</project>

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--xml方式声明自己开发的bean--><bean id="cat" class="com.axy.bean.Cat"/><bean id="dog" class="com.axy.bean.Dog"/>
</beans>

待注入对象:

public class Dog {...
}
public class Cat {...
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name); // 打印所有 bean 的名称}}
}

运行结果如下:

在这里插入图片描述
注:如果 application.xml 的 bean 标签不指定 id 属性,那么默认 bean 的名称为 全限定类名#索引 的形式,运行结果如下:

在这里插入图片描述


xml 方式声明第三方开发的 bean:

pom 中添加如下坐标:

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version>
</dependency>

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!--xml方式声明自己开发的bean--><bean id="cat" class="com.axy.bean.Cat"/><bean id="dog" class="com.axy.bean.Dog"/><!--xml方式声明第三方开发的bean--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>

那么这样会使用 DruidDataSource 的默认构造函数来创建 Bean 对象。控制台打印结果如下:
在这里插入图片描述

相关链接:Spring 从入门到精通系列 05 —— Spring 依赖注入的三种方式


方式二:XML + 注解方式声明 bean

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!--指定加载bean的位置,component--><context:component-scan base-package="com.axy.bean"/>
</beans>

待注入对象:

@Component("dog") // 如果不写 value 属性,当前 value 默认为类名首字母小写
public class Dog {...
}@Component("cat")
public class Cat {...
}

注:如果要注入controller、service 或者 dao 的 Bean 添加至 IOC 容器,要使用其衍生注解 @Controller 、@Service、@Repository

相关链接:Spring 从入门到精通系列 06 —— Spring 中的 IOC 常用注解

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name); // 打印所有 bean 的名称}}
}

控制台打印结果如下:
在这里插入图片描述

问题: 第三方 bean(如:druid),没有由 ioc 容器创建出来。

解决步骤:① 新建配置类,在其里面定义第三方 bean,并在该配置类上添加 @Component 或 @Configuration 注解使得该方法参与解析。
     ② 在 application.xml 中添加扫描当前配置类的路径信息。

配置类中添加返回第三方 Bean 对象的方法,并添加相应注解:

//@Component
@Configuration
public class DbConfig {@Beanpublic DruidDataSource dataSource(){ // 方法的名称代表了当前 bean 的名称return new DruidDataSource();}
}
<!--指定加载bean的位置,component-->
<context:component-scan base-package="com.axy.bean, com.axy.config"/>

控制台打印结果如下:
在这里插入图片描述
注:@Configuration 注解的定义上添加了 @Component,因此配置类使用 @Component也是没问题的,但推荐写 @Configuration
在这里插入图片描述


方式三:注解方式声明配置类

当前工程目录如下:
在这里插入图片描述

声明配置类,并使用 @ComponentScan 注解指定要扫描的包:

@ComponentScan(value = {"com.axy.bean", "com.axy.config"})
public class SpringConfig {
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}

控制台打印结果:
在这里插入图片描述
注:因为使用 AnnotationConfigApplicationContext 方法指定加载了 SpringConfig 这个类,那么该类会被加载成 bean 对象,并且类上面的 @Configuration 注解可不用添加了,并且里面也可添加创建第三方 bean 的方法(但一般不这么写)。


扩展一:@Bean 返回的对象和真实 Bean 对象可能不是一个

当前工程目录如下:
在这里插入图片描述

在 bean 包下新建 DogFactoyBean 类,并实现 FactoryBean 接口:

import org.springframework.beans.factory.FactoryBean;public class DogFactoryBean implements FactoryBean<Dog> {@Overridepublic Dog getObject() throws Exception {return new Dog();}@Overridepublic Class<?> getObjectType() { // 返回工厂所生产对象的类型// 如果泛型是接口类型,那么当前返回其实现类的字节码return Dog.class;}@Overridepublic boolean isSingleton() { // 工厂构建的对象是否是单例return true;}
}

将 Dog 类上的注解去掉:

//@Component("dog")
public class Dog {...
}

添加返回 DogFactoryBean 类的方法,并将其返回值生成 Bean 对象:

@ComponentScan(value = {"com.axy.bean"})
public class SpringConfig {@Beanpublic DogFactoryBean dog(){ // Bean的名称是当前方法名return new DogFactoryBean(); // 返回对象的类型应该是 “DogFactoryBean”}
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx =new AnnotationConfigApplicationContext(SpringConfig.class);Object bean = ctx.getBean("dog");System.out.println(bean.getClass());}
}

控制台打印结果:
在这里插入图片描述

从结果可以看出,public DogFactoryBean dog(){…} 要返回的类型是 DogFactoryBean,但真实返回的类型是 Dog

结论:@Bean 返回的对象类型和真实 Bean 对象类型可能不是一个。


扩展二:加载配置类的同时,加载配置文件(系统迁移)

场景:目前需要做一个系统的二次开发,原有系统用的是配置文件的形式声明 Bean,现准备用注解的形式配置声明 Bean。如何在注解的声明中将原有的配置文件加载进来呢?

当前工程目录如下:
在这里插入图片描述

添加旧配置类 applicationContext2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="tiger" class="com.axy.bean.Tiger" />
</beans>

bean 包下添加 Tiger 类:

public class Tiger {private Integer age;public void setAge(Integer age) {this.age = age;}@Overridepublic String toString() {return "Tiger{" +"age=" + age +'}';}
}

可以在配置类上使用 @ImportResource 注解将配置文件加载进来:

@ComponentScan("com.axy.bean")
@ImportResource("applicationContext2.xml") // 加载旧配置文件
public class SpringConfig2 {
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig2.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}

控制台打印结果:
在这里插入图片描述


扩展三:@ImportResource、@Bean、@Component 加载优先级

首先给出结论:@ImportResource、@Bean、@Component 要注入的 Bean 的名称相同时,优先级表现为:@ImportResource > @Bean > @Component。

当前工程目录如下:
在这里插入图片描述

修改 applicationContext2.xml,Tiger 类采用 set 方法注入,age 设置为 30:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--set方法注入--><bean id="tiger" class="com.axy.bean.Tiger"><property name="age" value="30"/></bean>
</beans>

新建配置类 SpringConfig3,添加生成 Bean 对象方法,其中 tiger 对象 age 设置为 20:

@ComponentScan(value = {"com.axy.bean"})
@ImportResource("applicationContext2.xml")
public class SpringConfig3 {@Beanpublic Tiger tiger(){Tiger tiger = new Tiger();tiger.setAge(20);return tiger;}
}

修改 Tiger 类,当被 @ComponentScan 扫描生成 bean 对象时,使其 age 初始化为 10:

@Component
public class Tiger {private Integer age = 10;...
}

测试类:

public class App3 {public static void main(String[] args) {ApplicationContext ctx =new AnnotationConfigApplicationContext(SpringConfig3.class);Tiger tiger = (Tiger) ctx.getBean("tiger");System.out.println(tiger);}
}

控制台打印结果:
在这里插入图片描述

当注释 @ImportResource(“applicationContext2.xml”),控制台打印结果如下:

在这里插入图片描述

结果表明:@ImportResource、@Bean、@Component 要注入的 Bean 的名称相同时,优先级表现为:@ImportResource > @Bean > @Component。


扩展四:@ImportResource 引入多个配置文件的优先级

首先给出结论:同名的 Bean 对象,后加载的配置会覆盖先加载的配置。

添加配置文件 applicationContext3.xml,Tiger 类采用 set 方法注入,age 设置为 40:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!--set方法注入--><bean id="tiger" class="com.axy.bean.Tiger"><property name="age" value="40"/></bean>
</beans>

用 @ImportResource 同时引入两个配置文件:

@ImportResource(value = {"applicationContext2.xml", "applicationContext3.xml"})
public class SpringConfig31 {
}

控制台打印结果:
在这里插入图片描述
如果交换引入顺序:

@ImportResource(value = {"applicationContext3.xml", "applicationContext2.xml"})
public class SpringConfig31 {
}

控制台打印结果:
在这里插入图片描述

因此得出结论:同名的 Bean 对象,后加载的配置会覆盖先加载的配置。


扩展五:proxyBeanMethods=true 生成代理对象

首先给出结论:proxyBeanMethods=true 可以保障当前配置类在 Spring 容器中生成的是代理对象,其里面定义的 Bean 是从容器中获取的,而不是重新创建的。

@Configuration 注解里面有一个属性 proxyBeanMethods,默认值为 true。

在这里插入图片描述
新建配置类 SpringConfig32,设置 proxyBeanMethods 属性

@Configuration(proxyBeanMethods = true)
public class SpringConfig32 {@Beanpublic Cat cat(){return new Cat();}
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig32.class);System.out.println(ctx.getBean("springConfig32"));System.out.println("---------------------------");System.out.println(ctx.getBean("cat"));System.out.println(ctx.getBean("cat"));System.out.println(ctx.getBean("cat"));}
}
proxyBeanMethods=trueproxyBeanMethods=false打印结果在这里插入图片描述在这里插入图片描述

结果表明:① 设置 proxyBeanMethods=true,生成的配置类对象是代理对象,通过其调用加载 Bean 的方法, 是从容器中获取的,而不是重新创建的。
     ② 设置 proxyBeanMethods=false,生成的配置类对象是普通对象,每次执行定义 Bean 的方法都会创建一个新的对象。

总结:配置类中设置 proxyBeanMethods=true,若其某一个方法可以得到对象,并且该对象被加载成 Bean。那么这个方法 在该配置类中 不论调用多少次,都是从容器中获取,即只会创建一次。

注:设置 proxyBeanMethods=true,里面的加载 Bean 的方法也要添加 @Bean 注解。


方式四:@Import 注解注入

当前工程目录如下:
在这里插入图片描述
添加配置类 SpringConfig4,使用 @Import 注解导入要注入的 bean 对应的字节码:

@Import(Dog.class) // 被导入的 bean (Dog类) 无需使用注解声明为 bean。
public class SpringConfig4 {
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig4.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}

控制台打印结果:

在这里插入图片描述

从结果可以看出与前文 Bean 名称不同的是,@Import 注解加载的 Bean 名称采用 全路径类名。

注:此形式可以有效的降低源代码与 Spring 技术的耦合度,在 spring 技术底层及诸多框架的整合中大量使用


使用 @Import 加载配置类:

使用 @Import 加载配置类 DbConfig:

@Import(value = {Dog.class, DbConfig.class})
public class SpringConfig4 {
}@Configuration
public class DbConfig {@Beanpublic DruidDataSource dataSource(){return new DruidDataSource();}
}

控制台打印结果:
在这里插入图片描述
结果表明:DbConfig 被加载了,并且配置类里面 Bean 的声明也会被加载。

如果去掉配置类里面的 @Configuration 注解,打印结果同上。

结论:使用 @Import 加载配置类,配置类可不用添加 @Configuration 注解。


方式五:上下文对象在容器初始化完毕后注入

上下文对象的 registerBean 方法,是 AnnotationConfigApplicationContext 独有的方法:

测试类:

public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ctx =new AnnotationConfigApplicationContext(SpringConfig4.class);// 上下文容器对象已经初始化完毕后,手工加载 beanctx.registerBean("monkey", Monkey.class, 1); // 参数三代表构造函数的参数ctx.registerBean("monkey", Monkey.class, 2);ctx.registerBean("monkey", Monkey.class, 3);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}System.out.println("-------------");Monkey monkey = ctx.getBean("monkey", Monkey.class);System.out.println(monkey);}
}public class Monkey {private Integer age;public Monkey() {}public Monkey(Integer age) {this.age = age;}@Overridepublic String toString() {return "Monkey{" +"age=" + age +'}';}
}

打印结果:
在这里插入图片描述

结果表明:上下文容器初始化后,注册了三次 monkey 对象,但最终容器中保留的是最后一次注册的对象。

注:如果使用 registerBean 方法的时候,没有指明 bean 的名称,除非待注入的对象使用 @Component 或其衍生注解指名 bean 的名称,否则名称默认类名首字母小写。


方式六:实现 ImportSelector 接口 ★

实现 ImportSelector 接口的类,实现对导入源的编程式处理。

当前工程目录如下:
在这里插入图片描述

添加 MyImportSelector 类,实现 ImportSelector 接口,并重写 selectImports 方法:

public class MyImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata metadata) {return new String[]{"com.axy.bean.Dog", "com.axy.bean.Cat"}; // 数组元素为全路径类名}
}public class Dog {}public class Cat {}

添加配置类 SpringConfig6,使用 @Import 引入 MyImportSelector 类:

@Import(MyImportSelector.class)
public class SpringConfig6 {
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig6.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}

控制台打印结果:
在这里插入图片描述


String[] selectImports(AnnotationMetadata metadata) 方法形参 metadata 代表元数据,描述的是使用该类 MyImportSelector 的对象。

public class MyImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata metadata) {System.out.println("------------------");System.out.println("提示:" + metadata.getClassName()); // 获取使用当前该类的对象的类名System.out.println(metadata.hasAnnotation("org.springframework.context.annotation.Configuration"));System.out.println("------------------");return new String[]{"com.axy.bean.Dog", "com.axy.bean.Cat"};}
}

控制台打印结果:
在这里插入图片描述

结果表明:使用类 MyImportSelector 类的对象,其类名是 SpringConfig6,并且该对象没有使用 @Configuration 注解。

medata 还有很多方法可以用,如:获取 SpringConfig6 是否包含指定注解,该注解是否有某种属性等。
因此,可以用 medata 做各种条件的判定,以此来决定是否加载指定的 Bean,即动态加载 Bean。

如以下代码:

public class MyImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata metadata) {boolean flag = metadata.hasAnnotation("org.springframework.context.annotation.Configuration");if (flag) {return new String[]{"com.axy.bean.Dog"};}return new String[]{"com.axy.bean.Cat"};}
}

注:源码中大量使用!


方式七:实现 ImportBeanDefinitionRegistrar 接口 ★

当前工程目录如下:
在这里插入图片描述

新建 MyRegistrar 类,实现 ImportBeanDefinitionRegistrar 接口,并重写 public void registerBeanDefinitions(…){…} 方法。

public class MyRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {// 1.使用元数据去做判定// 2.返回值是 void,不同于方式六中直接加载 Bean 的形式// 创建 beanDefinition 对象,并将该对象使用 registry 注册进容器当中BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Tiger.class).getBeanDefinition();registry.registerBeanDefinition("tiger", beanDefinition); // registerBeanDefinition 参数一:bean 名称,参数二:beanDefinition对象}
}

registerBeanDefinitions(…) 方法:
① 参数一:元数据对象,可以对使用该类 MyRegistrar 的对象各种判定;
② 参数二: Bean 注册器对象,可以实现对容器中 bean的裁定。如:例设置 bean 的单例多例等…

在这里插入图片描述

新建 SpringConfig7 类,并通过 @Import 注解引入 MyRegistrar 类:

@Import(MyRegistrar.class)
public class SpringConfig7 {
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx =new AnnotationConfigApplicationContext(SpringConfig7.class);String[] names = ctx.getBeanDefinitionNames();for (String name : names) {System.out.println(name);}}
}

控制台打印结果:
在这里插入图片描述

总结: 相比于方式六中实现 ImportSelector 接口,方式七实现 ImportBeanDefinitionRegistrar 接口将 bean 的管理开放了出来。


如果配置类中引入多个 ImportSelector 接口的实现类,那么对 Bean 对象的裁定由顺序决定。如以下代码:

新建 BookService 接口和实现类:

public interface BookService {public void check();
}public class BookServiceImpl1 implements BookService {@Overridepublic void check() {System.out.println("book service 1...");}
}public class BookServiceImpl2 implements BookService {@Overridepublic void check() {System.out.println("book service 2...");}
}

新建注册器,并分别注册成同名 bean:

public class MyRegistrar1 implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl1.class).getBeanDefinition();registry.registerBeanDefinition("bookService", beanDefinition);}
}public class MyRegistrar2 implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl2.class).getBeanDefinition();registry.registerBeanDefinition("bookService", beanDefinition);}
}

配置类引入两个注册器实现类:

@Import({MyRegistrar1.class, MyRegistrar2.class})
public class SpringConfig71 {
}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig71.class);BookService bookService = ctx.getBean("bookService", BookService.class);bookService.check();}
}

控制台打印结果:
在这里插入图片描述

如果调换引用顺序,则 Bean 对象的最终裁定也会发生变化,即控制台将打印:book service 1…


方式八:实现 BeanDefinitionRegistryPostProcessor 接口

当前工程目录如下:

在这里插入图片描述

新建 MyPostProcessor 类,实现 BeanDefinitionRegistryPostProcessor 方法,并重写里面的方法:

public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {BeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(BookServiceImpl3.class).getBeanDefinition();beanDefinitionRegistry.registerBeanDefinition("bookService", beanDefinition);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
}

方法 public void postProcessBeanDefinitionRegistry(…){…}, 后处理并定义注册 Bean。简而言之,通过 BeanDefinition 的注册器注册实名bean,实现对容器中 bean 的最终裁定。

引荐配置类,并引用两个注册器和后处理注册器 MyPostProcessor:

@Import({MyPostProcessor.class, MyRegistrar1.class, MyRegistrar2.class})
public class SpringConfig8 {}

测试类:

public class App {public static void main(String[] args) {ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig8.class);BookService bookService = ctx.getBean("bookService", BookService.class);bookService.check();}
}

控制台打印结果:
在这里插入图片描述

结果表明:后处理器的实现类会在所有 Bean 都注册定义后再进行处理,如果有同名 Bean,则会覆盖前面注册的 Bean。

另外,如果配置类引用多个后处理器的实现类,则按照后处理器实现类的顺序对 Bean 进行最终的裁定。


参考链接:黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)

查看全文

99%的人还看了

猜你感兴趣

版权申明

本文"由浅入深,详细总结 Spring 八种加载 Bean 的方式":http://eshow365.cn/6-25381-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!