Spring中用于装配组件的常见扩展点的介绍

简介: 在Spring的项目中,组件的组装离不开Spring提供的一些扩展点,本文对BeanFactoryPostProcessor、FactoryBean、BeanPostProcessor、@Import这四个扩展点做了简单的介绍。

前言

什么是BeanDefinition

BeanDefinition表示Bean定义,它存放了很多属性用来描述一个Bean的特点,如表示Bean类型的class属性,表示Bean作用域、单例或原型等的scope属性,表示Bean是否是懒加载的lazyInit属性,表示Bean初始化时要执行的方法的initMethodName属性等等。

在Spring中,bean的创建依赖于BeanDefinition,若容器中不存在BeanDefinition那么这个bean就不会被创建,所以某个类需要被创建成为一个bean就需要为其创建成BeanDefinition,而这些BeanDefinition会存放在容器中

在Spring中,我们经常会通过@Bean和@Component(@Service,@Controller)来定义一个bean,当然也可以自定义一个BeanDefinition直接存放到容器中。

什么是配置类

在Spring中,当某个类上存在@Configuration,并且proxyBeanMethods为false时,这个类是lite配置类,若这个值为true或null,这个类是full配置类;或者不存在@Configuration,但是只要存在@Component、@ComponentScan、@Import、@ImportResource四个中的一个,这个类也是lite配置类;或者不存在@Configuration,只要存在@Bean注解了的方法,这个类也是lite配置类。Spring可以通过这些配置类将这些能够生成Bean类封装成BeanDefinition,注册到容器中。

BeanFactoryPostProcessor接口

   BeanFactoryPostProcessor,即bean工厂后置处理器,这个接口提供了一个postProcessBeanFactory()方法。

@FunctionalInterfacepublicinterfaceBeanFactoryPostProcessor {
voidpostProcessBeanFactory(ConfigurableListableBeanFactorybeanFactory) throwsBeansException;
}

  在Spring启动过程中,Spring会将容器中存放的所有的BeanFactoryPostProcessor实例化,后执行它的postProcessBeanFactory()。执行这个方法时,会传入一个ConfigurableListableBeanFactory类型的入参,这个入参就是我们的Spring容器,我们可以通过自定义BeanFactoryPostProcessor的方式实现对Spring的ConfigurableListableBeanFactory容器进行一些操作。

FactoryBean接口

FactoryBean提供了一个getObject()方法,当某个bean实现了FactoryBean,我们根据其对应的beanName执行getBean()获取bean对象时,返回的是其getObject()方法的结果。

publicinterfaceFactoryBean<T> {
StringOBJECT_TYPE_ATTRIBUTE="factoryBeanObjectType";
@NullableTgetObject() throwsException;
@NullableClass<?>getObjectType();
defaultbooleanisSingleton() {
returntrue;
    }
}

那么基于此,在我们实际开发过程中利用getObject()生成一个代理对象,通过动态代理的方式来实现一些逻辑功能。

BeanPostProcessor接口

BeanPostProcess表示bean的后置处理器,它和BeanFactoryPostProcessor类似,BeanFactoryPostProcessor是在BeanFactory的创建过程做一些操作,而BeanPostProcessor则是在Bean的创建过程中做一些操作。

在spring中,一个bean的创建过程可以大致分为实例化、属性填充、初始化、注册销毁逻辑这些步骤,而这个过程中Spring会在不同位置执行相应的BeanPostProcessor的方法,来完成bean的创建,那么我们可以通过自定义不同BeanPostProcessor的方式来实现对特定的一些bean的组装。

BeanPostProcessor接口

BeanPostProcess中提供了postProcessBeforeInitialization()和postProcessAfterInitialization()两个方法,这两个的方法入参中都包含了bean对象,且返回值都为Object。

publicinterfaceBeanPostProcessor {
@NullabledefaultObjectpostProcessBeforeInitialization(Objectbean, StringbeanName) throwsBeansException {
returnbean;
    }
@NullabledefaultObjectpostProcessAfterInitialization(Objectbean, StringbeanName) throwsBeansException {
returnbean;
    }
}

Spring会在初始化bean时,在执行bean的初始化方法的前后来分别执行这两个方法。其中postProcessAfterInitialization()的返回值将被作为最终生成的对象返回,例如开启AOP后,bean的AOP代理对象就是通过执行这个方法生成的。

InstantiationAwareBeanPostProcessor接口

InstantiationAwareBeanPostProcessor是BeanPostProcessor的一个子接口,这个接口会在Bean实例化前、属性设置之前、属性设置时执行相应的方法来操作bean。

在创建bean之前,spring会执行容器中所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法,这个操作称为实例化前。在执行时,若postProcessBeforeInstantiation()方法返回一个非空对象,那么就会执行InstantiationAwareBeanPostProcessor的applyBeanPostProcessorsAfterInitialization()方法,若同样返回的是非空对象,那么spring会将这个对象作为生成的bean,不再去执行后面的创建bean的操作了。基于此,我们可以定义InstantiationAwareBeanPostProcessor来实现创建我们希望的bean对象。

@NullabledefaultObjectpostProcessBeforeInstantiation(Class<?>beanClass, StringbeanName) throwsBeansException {
returnnull;
}

在属性填充中属性设置之前,spring会执行容器中的InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法,这个方法的入参包括spring实例对象,返回一个boolean值,若这个返回值为false的话,则后面为bean进行属性赋值的操作将不再执行。那么我们就可以利用这个扩展点对特定一些bean实例进行一些操作,且还可以控制是否让spring对这bean进行属性赋值操作。

defaultbooleanpostProcessAfterInstantiation(Objectbean, StringbeanName) throwsBeansException {
returntrue;
}

属性设置,即为bean中的一些属性赋值,bean的属性注入就在这里进行的。在这里,spring会把bean对象做为入参执行InstantiationAwareBeanPostProcessor的postProcessProperties()方法来操作bean,其中@Autowired和@Resource的属性的注入就在这完成的。参考于@Autowired和@Resource解析,我们可以自定义注解来完成属性的注入操作。

@NullabledefaultPropertyValuespostProcessProperties(PropertyValuespvs, Objectbean, StringbeanName)
throwsBeansException {
returnnull;
    }

MergedBeanDefinitionPostProcessor

在bean实例化后属性赋值之前,Spring会执行容器中所有MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法,即后置处理合并后的BeanDefinition。

publicinterfaceMergedBeanDefinitionPostProcessorextendsBeanPostProcessor {
voidpostProcessMergedBeanDefinition(RootBeanDefinitionbeanDefinition, Class<?>beanType, StringbeanName);
defaultvoidresetBeanDefinition(StringbeanName) {
    }
}

执行postProcessMergedBeanDefinition()方法时,Spring会将正在创建的bean的RootBeanDefinition作为入参传入到方法中,那么我们就可以通过自定义MergedBeanDefinitionPostProcessor方式来实现对特定的一些bean的BeanDefinition诸如bean的属性值、bean的初始化方法、bean的销毁方法等一些属性进行修改。


@Import注解

@Import注解的作用主要有两个,一个引入一个配置类让Spring去解析,另外一个作用是将用户自定义的bean定义注册到容器中。

@Import注解只有一个value属性,这个属性接收的是一个Class对象的数组,这个Class对象可以是一个实现了ImportSelector接口的类,可以是一个实现了ImportBeanDefinitionRegistrar接口的类,也可以是一个普通的类。

引入实现了ImportSelector的类

ImportSelector中有一个selectImports()方法,这个方法会返回一个类的全限定类名的数组,在spring处理的过程中会将实现了这接口类实例化,然后执行selectImports()方法,获取返回结果。

publicinterfaceImportSelector {
String[] selectImports(AnnotationMetadataimportingClassMetadata);
@NullabledefaultPredicate<String>getExclusionFilter() {
returnnull;
    }
}

这个接口的作用等价于@Import注解,其selectImports()方法就等同于@Import的value属性,其selectImports()返回的String数组中的值会被转换成Class对象后做@Import注解一样的处理。对于引入ImportSelector接口的类的使用,我们可以查看一下Spring提供的开启事务管理的注解@EnableTransactionManagement。


引入实现了ImportBeanDefinitionRegistrar的类

ImportBeanDefinitionRegistrar中有一个registerBeanDefinitions()方法,在spring处理的过程中也会将实现了这接口类实例化,然后执行它的registerBeanDefinitions()方法。

publicinterfaceImportBeanDefinitionRegistrar {
defaultvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata, BeanDefinitionRegistryregistry,
BeanNameGeneratorimportBeanNameGenerator) {
registerBeanDefinitions(importingClassMetadata, registry);
    }
defaultvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata, BeanDefinitionRegistryregistry) {
    }
}

要注意是registerBeanDefinitions()方法中有一个BeanDefinitionRegistry类型的入参,那么我们就可以通过执行这个方法来实现将一些BeanDefinition注册到容器中。比如Spring开启AOP就注解@EnableAspectJAutoProxy,它就是通过导入一个实现的ImportBeanDefinitionRegistrar接口的类AspectJAutoProxyRegistrar,来实现将生成动态代理的后置处理器AnnotationAwareAspectJAutoProxyCreator注册到容器中的。

引入普通的类

 普通的类指的就是即没有实现ImportSelector接口,又没有实现ImportBeanDefinitionRegistrar接口的类,Spring在处理的过程中就会把当中一个配置类进行解析。

目录
相关文章
|
5月前
|
NoSQL 安全 Java
深入理解 RedisConnectionFactory:Spring Data Redis 的核心组件
在 Spring Data Redis 中,`RedisConnectionFactory` 是核心组件,负责创建和管理与 Redis 的连接。它支持单机、集群及哨兵等多种模式,为上层组件(如 `RedisTemplate`)提供连接抽象。Spring 提供了 Lettuce 和 Jedis 两种主要实现,其中 Lettuce 因其线程安全和高性能特性被广泛推荐。通过手动配置或 Spring Boot 自动化配置,开发者可轻松集成 Redis,提升应用性能与扩展性。本文深入解析其作用、实现方式及常见问题解决方法,助你高效使用 Redis。
556 4
|
6月前
|
安全 Java 数据安全/隐私保护
微服务——SpringBoot使用归纳——Spring Boot中集成 Shiro——Shiro 三大核心组件
本课程介绍如何在Spring Boot中集成Shiro框架,主要讲解Shiro的认证与授权功能。Shiro是一个简单易用的Java安全框架,用于认证、授权、加密和会话管理等。其核心组件包括Subject(认证主体)、SecurityManager(安全管理员)和Realm(域)。Subject负责身份认证,包含Principals(身份)和Credentials(凭证);SecurityManager是架构核心,协调内部组件运作;Realm则是连接Shiro与应用数据的桥梁,用于访问用户账户及权限信息。通过学习,您将掌握Shiro的基本原理及其在项目中的应用。
247 0
|
6月前
|
负载均衡 Java Nacos
Spring Cloud五大组件
Spring Cloud五大组件
|
2月前
|
JSON 前端开发 Java
Spring MVC 核心组件与请求处理机制详解
本文解析了 Spring MVC 的核心组件及请求流程,核心组件包括 DispatcherServlet(中央调度)、HandlerMapping(URL 匹配处理器)、HandlerAdapter(执行处理器)、Handler(业务方法)、ViewResolver(视图解析),其中仅 Handler 需开发者实现。 详细描述了请求执行的 7 步流程:请求到达 DispatcherServlet 后,经映射器、适配器找到并执行处理器,再通过视图解析器渲染视图(前后端分离下视图解析可省略)。 介绍了拦截器的使用(实现 HandlerInterceptor 接口 + 配置类)及与过滤器的区别
202 0
|
6月前
|
前端开发 Java 数据库连接
Spring MVC 扩展和SSM框架整合
通过以上步骤,我们可以将Spring MVC扩展并整合到SSM框架中。这个过程包括配置Spring MVC和Spring的核心配置文件,创建控制器、服务层和MyBatis的Mapper接口及映射文件。在实际开发中,可以根据具体业务需求进行进一步的扩展和优化,以构建更加灵活和高效的企业级应用程序。
140 5
|
10月前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
877 61
|
10月前
|
消息中间件 Java 数据库
解密Spring Boot:深入理解条件装配与条件注解
Spring Boot中的条件装配与条件注解提供了强大的工具,使得应用程序可以根据不同的条件动态装配Bean,从而实现灵活的配置和管理。通过合理使用这些条件注解,开发者可以根据实际需求动态调整应用的行为,提升代码的可维护性和可扩展性。希望本文能够帮助你深入理解Spring Boot中的条件装配与条件注解,在实际开发中更好地应用这些功能。
189 2
|
XML 缓存 Java
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
163 10
|
XML 存储 Java
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧