从前天开始气温飞升,三十七八度,这谁受得了,看看代码降降温~
文章目录
- 什么是注册bean
- @Autowired、@Resource及@Inject等
- @Component及@Service等
- @Configuration及@Bean
- spring.factories文件
- @Import和ImportSelector使用
- @Import及ImportBeanDefinitionRegistrar
- 以上(方便跳转)
什么是注册bean
Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans
IOC 容器具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。
而注册bean其实粗暴理解就是把bean放到IOC容器内。(就是这么简单)
话不多说,也没啥可说,直接列举方式,不做原理说明:
@Autowired、@Resource及@Inject等
其实这些注解并不是标准意义的注册bean方式,这些是在bean实例化完成后进行属性注入时候所使用的,但是也可以列为注册bean的方式,比较简单就不列举了,想要了解关于@Autowired及@Resource相关的可以看之前的文章:@Autowired和@Resource原理源码知识点详解
@Component及@Service等
需要配合@ComponentScan使用,保证可以扫描到,其实对于spring boot项目来说,保证Application启动类的路径为需要扫描组件上级路径即可。(很简单不具体说了啊)
@Configuration及@Bean
默认bean的名称就是其方法名,上面代码就是注册了一个名称为phliServiceBean,类型为PhliServiceImpl的bean。当然也可以指定名称:
@Bean注解说明:
- @Bean 注解作用在方法上
- @Bean 指示一个方法返回一个 Spring 容器管理的 Bean,也就是说方法返回值就是给Springr容器装配的bean
- @Bean 一般和 @Component 或者 @Configuration 一起使用,也可以在 @Service 里使用,没有特定要求,主要看项目的需求。
- @Bean 注解默认作用域为单例 singleton 作用域,可通过 @Scope(“prototype”) 设置为原型作用域
spring.factories文件
spring.factories文件是Spring Boot自动配置的核心文件之一,它的作用是将各种自动配置类与对应的配置类集中在一起,方便Spring Boot自动装配。在Spring Boot启动时,它会扫描classpath下所有的spring.factories文件,加载其中的自动配置类,并将它们注入到Spring ApplicationContext中,使得项目能够自动运行。该文件的格式为键值对,键是自动配置类的全限定名,值是该自动配置类所对应的配置类的全限定名,如:
org.springframework.context.ApplicationContextInitializer=\
cn.ph.software.initial.MyselfApplicationContextInitializer
org.springframework.context.ApplicationListener=cn.ph.software.listener.TestListener
自定义初始化器MyselfApplicationContextInitializer代码如下(举个例子):
简单说下原理:
- 查看@SpringBootApplication注解。
- 查看@EnableAutoConfiguration注解。
- @Import(AutoConfigurationImportSelector.class)查看AutoConfigurationImportSelector类。
- 可以看到AutoConfigurationImportSelector类实现了DeferredImportSelector接口。
- 而DeferredImportSelector接口继承了ImportSelector接口。ImportSelector接口有如下方法:
String[] selectImports(AnnotationMetadata importingClassMetadata);
- 查看AutoConfigurationImportSelector类的selectImports方法:
可以看到最后调用loadFactoryNames( )方法,这个方法的逻辑就是扫描pom文件中引入的其他starter中的spring.factories文件。
@Import和ImportSelector使用
ImportSelector接口是spring boot提供的接口,包含一个用于代码方式注册多个bean的方法,spring boot内部的DeferredImportSelector就是该接口子接口,其实在上一个节点中已经有所体现,最经典的使用就是@EnableAutoConfiguration注解,通过实现ImportSelector接口,然后在selectImports方法内返回所需要注册类的全限定名。
AutoConfigurationImportSelector就是实现了ImportSelector接口。
自定义实现:
配合@Configuration注解使用。
@Import及ImportBeanDefinitionRegistrar
ImportBeanDefinitionRegistrar,该接口主要用来注册beanDefinition,许多需要集成的第三方框架都需要实现该接口执行registerBeanDefinitions方法然后配合@Import将特定bean注册到spring容器中。
当然也包括spring许多@Enable相关的注解也用到了这种方式,最常见的就是动态代理相关注解:@EnableAspectJAutoProxy。接下来看下该注解源码:
看下AspectJAutoProxyRegistrar类:
BeanDefinitionRegistry 是一个接口,它定义了关于 BeanDefinition 的注册、移除、查询等一系列的操作。可以通过执行 registerBeanDefinition 方法,将Bean的名称和对应的BeanDefinition放入容器中,后续获取Bean也是从这个容器中获取,从而实现了bean的注册。