目录

一.自动配置

1.1 bean的加载方式(八种)

1.1.1 XML方式声明bean

1.1.2 XML+注解方式声明bean 

1.1.3 纯注解方式声明bean

1.1.4 FactoryBean接口

1.1.5 加载旧系统的XML配置文件

1.1.6 proxyBeanMethods

1.1.7 使用@Import注解导入要注入的bean对应的字节码

1.1.8 使用上下文对象在容器初始化完毕后注入bean

1.1.9  通过实现ImportSelector接口以创建bean

1.1.10 通过实现ImportBeanDefinitionRegistrar接口以创建bean

1.1.11 实现BeanDefinitionRegistryPostProcessor接口以创建bean


一.自动配置

1.1 bean的加载方式(八种)

以下加载方式都是在spring项目中进行的,而非springboot环境,所以其打印出来的IOC容器中的bean并不多。

1.1.1 XML方式声明bean

spring boot 重新加载bean springboot加载bean原理_spring

1.1.2 XML+注解方式声明bean 

1.在配置文件中定义哪些包及其子包被扫描:

spring boot 重新加载bean springboot加载bean原理_spring_02

2.在被扫描的包中使用注解将某些类定义为bean,这些类包括自定义类和第三方类

 使用@Component及其衍生注解@Controller 、@Service、@Repository定义bean

spring boot 重新加载bean springboot加载bean原理_spring_03

使用@Bean定义第三方bean,并将所在类定义为配置类或Bean

spring boot 重新加载bean springboot加载bean原理_spring_04

1.1.3 纯注解方式声明bean

只需将xml配置文件转为配置类即可

spring boot 重新加载bean springboot加载bean原理_java_05

1.1.4 FactoryBean接口

先看下面这个例子:

第一步:定义一个工厂类,让这个工厂类实现FactoryBean接口,并重写这个接口中的方法

spring boot 重新加载bean springboot加载bean原理_加载_06

第二步:将这个工厂类定义为配置类中的第三方bean

spring boot 重新加载bean springboot加载bean原理_加载_07

第三步:加载这个配置类,并查看类中方法返回的bean的类型

spring boot 重新加载bean springboot加载bean原理_spring_08

结论:可以发现,这个工厂bean产生的bean的类型是其方法的返回值类型

spring boot 重新加载bean springboot加载bean原理_java_09

1.1.5 加载旧系统的XML配置文件

我们在旧系统上开发新功能的时候,新功能可能会采用注解的方式加载bean,而旧系统可能采用xml配置文件的方式加载bean,这个时候我们就要在配置类中使用@ImportResource注解加载旧系统的配置文件,以便把旧系统的bean跟新功能的bean都加到spring容器中。

spring boot 重新加载bean springboot加载bean原理_java_10

1.1.6 proxyBeanMethods

@Configuratiion注解中有一个proxyBeanMethods属性。使用proxyBeanMethods=true可以保障调用bean中方法(类中,类外调用都有效果)得到的对象是从容器中获取的而不是重新创建的。

例如:

第一步:声明一个配置类,将proxyBeanMethods置为true,并在配置类中定义一个bean。

spring boot 重新加载bean springboot加载bean原理_java_11

第二步:加载配置类,并从容器中取出springConfig33这个bean执行其cat()方法

spring boot 重新加载bean springboot加载bean原理_加载_12

 第三步:查看将proxyBeanMethods置为true的效果

spring boot 重新加载bean springboot加载bean原理_spring boot_13

结论:可以发现将proxyBeanMethods置为true后,调用这个bean的方法产生的对象都是同一个。

1.1.7 使用@Import注解导入要注入的bean对应的字节码

步骤:

第一步:使用@Import注解导入要注入的bean对应的字节码

spring boot 重新加载bean springboot加载bean原理_XML_14

第二步:加载第一步中的配置文件,并取出SpringConfig4这个bean

spring boot 重新加载bean springboot加载bean原理_加载_15

结论:发现这个bean已加入到spring容器中

spring boot 重新加载bean springboot加载bean原理_XML_16

1.1.8 使用上下文对象在容器初始化完毕后注入bean

spring boot 重新加载bean springboot加载bean原理_java_17

1.1.9  通过实现ImportSelector接口以创建bean

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

第一步:定义MyImportSelector类实现ImportSelector接口

spring boot 重新加载bean springboot加载bean原理_java_18

 第二步:创建SpringConfig6类,导入MyImportSelector.class

spring boot 重新加载bean springboot加载bean原理_spring boot_19

第三步:运行App6类,查看请其中是否有对应的bean

spring boot 重新加载bean springboot加载bean原理_spring_20

结果:

spring boot 重新加载bean springboot加载bean原理_spring_21

1.1.10 通过实现ImportBeanDefinitionRegistrar接口以创建bean

导入实现了ImportBeanDefinitionRegistrar接口的类,通过BeanDefinition的注册器注册实名bean,实现对 容器中bean的裁定,例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果。

第一个形参的作用跟上一种方法的形参相同,第二个形参的作用如下图所示

spring boot 重新加载bean springboot加载bean原理_XML_22

1.1.11 实现BeanDefinitionRegistryPostProcessor接口以创建bean

导入实现了BeanDefinitionRegistryPostProcessor接口的类,通过BeanDefinition的注册器注册实名bean, 实现对容器中bean的最终裁定

此方法中的形参跟上一个方法中的第二个形参作用相同。如果一个项目中定义了多个同名bean,此方法定义的bean会覆盖其他的同名bean。

spring boot 重新加载bean springboot加载bean原理_加载_23

总结:bean的加载方式也不止这八种,如果感兴趣,可以自己再去找来学习。