前言
什么是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()方法。
publicinterfaceBeanFactoryPostProcessor { 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"; TgetObject() throwsException; Class<?>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 { defaultObjectpostProcessBeforeInitialization(Objectbean, StringbeanName) throwsBeansException { returnbean; } defaultObjectpostProcessAfterInitialization(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对象。
defaultObjectpostProcessBeforeInstantiation(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解析,我们可以自定义注解来完成属性的注入操作。
defaultPropertyValuespostProcessProperties(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); defaultPredicate<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在处理的过程中就会把当中一个配置类进行解析。