@Import(JpaAuditingRegistrar.class)
public @interface EnableJpaAuditing {
}
class EnableJpaAuditing extends AuditingBeanDefinitionRegistrarSupport implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
registerBeanConfigurerAspectIfNecessary(registry);
super.registerBeanDefinitions(annotationMetadata, registry) {
// 注册AuditHandler的Bean,"jpaAuditingHandler":AuditingHandler,AuditingHandler就是一个类
AbstractBeanDefinition ahbd = registerAuditHandlerBeanDefinition(registry, getConfiguration(annotationMetadata));
// 注册审计的实体监听器
registerAuditListenerBeanDefinition(ahbd, registry);
}
// 注册AuditingBeanFactoryPostProcessor后置处理器
registerInfrastructureBeanWithId(BeanDefinitionBuilder.rootBeanDefinition(AuditingBeanFactoryPostProcessor.class).getRawBeanDefinition(), AuditingBeanFactoryPostProcessor.class.getName(), registry);
}
// 注册审计的实体监听器
protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandlerDefinition, BeanDefinitionRegistry registry) {
// 如果不存在JpaMetamodelMappingContext,注册该JpaMetamodelMappingContextFactoryBean
// MappingContext是用来映射实体与数据库之间关系的机制
if (!registry.containsBeanDefinition(JPA_MAPPING_CONTEXT_BEAN_NAME)) {
registry.registerBeanDefinition(JPA_MAPPING_CONTEXT_BEAN_NAME, new RootBeanDefinition(JpaMetamodelMappingContextFactoryBean.class));
}
// 注册实体监听器,就是利用JPA规范中,对实体监听的@PrePersist,@PreUpdate注解处理
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(AuditingEntityListener.class);
// 设置auditingHandler属性
builder.addPropertyValue("auditingHandler", ParsingUtils.getObjectFactoryBeanDefinition(getAuditingHandlerBeanName(), null));
// 注册AuditingEntityListener该Bean
registerInfrastructureBeanWithId(builder.getRawBeanDefinition(), AuditingEntityListener.class.getName(), registry);
}
// 注册基本的Bean
protected void registerInfrastructureBeanWithId(AbstractBeanDefinition definition, String id, BeanDefinitionRegistry registry) {
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(id, definition);
}
// 注册AuditHandler的Bean,"jpaAuditingHandler":AuditingHandler,AuditingHandler就是一个类
private AbstractBeanDefinition registerAuditHandlerBeanDefinition(BeanDefinitionRegistry registry, AuditingConfiguration configuration) {
// 新建用于创建AuditHandlerBean的Builder
BeanDefinitionBuilder builder = getAuditHandlerBeanDefinitionBuilder(configuration);
// 生成AuditHandler的BeanDefinition
AbstractBeanDefinition ahbd = builder.getBeanDefinition();
// 注册AuditHandler的Bean,"jpaAuditingHandler":AuditingHandler,AuditingHandler就是一个类
registry.registerBeanDefinition(getAuditingHandlerBeanName(), ahbd);
return ahbd;
}
// 新建用于创建AuditHandlerBean的Builder
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
// 给AuditingHandler处理类设置属性
BeanDefinitionBuilder builder = super.getAuditHandlerBeanDefinitionBuilder(configuration) {
// AuditingHandler:真正给实体设置公共属性的处理类
return configureDefaultAuditHandlerAttributes(configuration, BeanDefinitionBuilder.rootBeanDefinition(AuditingHandler.class));
}
// 设置构造函数参数
return builder.addConstructorArgReference(JPA_MAPPING_CONTEXT_BEAN_NAME);
}
// 给AuditorAware引用创建一个懒加载的Bean,等需要用到AuditorAware再进行加载
private BeanDefinition createLazyInitTargetSourceBeanDefinition(String auditorAwareRef) {
// 自定义代理的数据源
BeanDefinitionBuilder targetSourceBuilder = rootBeanDefinition(LazyInitTargetSource.class);
// 设置属性
targetSourceBuilder.addPropertyValue("targetBeanName", auditorAwareRef);
// 创建该代理的FactoryBean
BeanDefinitionBuilder builder = rootBeanDefinition(ProxyFactoryBean.class);
// 设置属性
builder.addPropertyValue("targetSource", targetSourceBuilder.getBeanDefinition());
// 返回auditorAwareRef设置的Bean的BeanDefinition
return builder.getBeanDefinition();
}
// 给AuditingHandler处理类设置属性
protected BeanDefinitionBuilder configureDefaultAuditHandlerAttributes(AuditingConfiguration configuration, BeanDefinitionBuilder builder) {
// 如果@EnableJpaAuditing设置了auditorAwareRef,表示要指定的AuditorAware来进行审计
if (StringUtils.hasText(configuration.getAuditorAwareRef())) {
// 给Bean设置属性
// 给AuditorAware引用创建一个懒加载的Bean,等需要用到AuditorAware再进行加载
builder.addPropertyValue(AUDITOR_AWARE, createLazyInitTargetSourceBeanDefinition(configuration.getAuditorAwareRef()));
} else {
// 设置根据类型进行注入,也就是从Spring中获取AuditorAware进行设置
builder.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
}
// 设置对应的属性
builder.addPropertyValue(SET_DATES, configuration.isSetDates());
builder.addPropertyValue(MODIFY_ON_CREATE, configuration.isModifyOnCreate());
// 设置时间处理器
if (StringUtils.hasText(configuration.getDateTimeProviderRef())) {
builder.addPropertyReference(DATE_TIME_PROVIDER, configuration.getDateTimeProviderRef());
} else {
builder.addPropertyValue(DATE_TIME_PROVIDER, CurrentDateTimeProvider.INSTANCE);
}
builder.setRole(AbstractBeanDefinition.ROLE_INFRASTRUCTURE);
return builder;
}
private void registerBeanConfigurerAspectIfNecessary(BeanDefinitionRegistry registry) {
// 是否存在org.springframework.context.config.internalBeanConfigurerAspect的Bean
if (registry.containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
return;
}
// 新增org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect这个Bean
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(BEAN_CONFIGURER_ASPECT_CLASS_NAME);
def.setFactoryMethodName("aspectOf");
def.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME, new BeanComponentDefinition(def, BEAN_CONFIGURER_ASPECT_BEAN_NAME).getBeanDefinition());
}
}
// 主要用于处理EntityManagerFactory的依赖关系
class AuditingBeanFactoryPostProcessor {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 校验是否存在org.springframework.context.config.internalBeanConfigurerAspect的Bean,在@EnableJpaAuditing已经开启了
try {
getBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME, beanFactory);
} catch (NoSuchBeanDefinitionException o_O) {
throw new IllegalStateException("Invalid auditing setup! Make sure you've used @EnableJpaAuditing or <jpa:auditing /> correctly!", o_O);
}
// 获取所有EntityManagerFactory的Bean的BeanName
Iterable<String> beanNames = getEntityManagerFactoryBeanNames(beanFactory);
for (String beanName : beanNames) {
// 设置EntityManagerFactory的依赖关系
// 依赖org.springframework.context.config.internalBeanConfigurerAspect这个Bean
BeanDefinition definition = getBeanDefinition(beanName, beanFactory);
definition.setDependsOn(addStringToArray(definition.getDependsOn(), BEAN_CONFIGURER_ASPECT_BEAN_NAME));
}
}
// 找Spring容器中EntityManagerFactory类型的Bean
public static Iterable<String> getEntityManagerFactoryBeanNames(ListableBeanFactory beanFactory) {
// 找Spring容器中EntityManagerFactory类型的Bean
String[] beanNames = beanNamesForTypeIncludingAncestors(beanFactory, EntityManagerFactory.class, true, false);
Set<String> names = new HashSet<>(asList(beanNames));
// 遍历所有的BeanName
for (String factoryBeanName : beanNames) {
// 保存转换之后的BeanName,因为可能是FactoryBean的Name
names.add(transformedBeanName(factoryBeanName));
}
return names;
}
}
// 真正给实体设置公共属性的处理类
class AuditingHandler {
// 因为创建AuditingHandler设置了builder.setAutowireMode(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
// 所以,针对属性,Spring会自动找类中所有Object类型属性对应的set方法,如果有就会注入
public void setAuditorAware(AuditorAware<?> auditorAware) {
this.auditorAware = Optional.of(auditorAware);
}
// 标记实体被创建了
public <T> T markCreated(T source) {
return touch(source, true);
}
// 标记实体被修改了
public <T> T markModified(T source) {
return touch(source, false);
}
// 处理
private <T> T touch(T target, boolean isNew) {
// 创建实体的包装器,就是为了扩展一些属性的set方法,例如setCreatedBy,setLastModifiedBy
Optional<AuditableBeanWrapper<T>> wrapper = factory.getBeanWrapperFor(target);
// 包装之后,又对实体进行解包
return wrapper.map(it -> {
// 获取AuditorAware返回的审计人,并给实体设置
Optional<Object> auditor = touchAuditor(it, isNew);
// 给实体设置创建/修改时间
Optional<TemporalAccessor> now = dateTimeForNow ? touchDate(it, isNew) : Optional.empty();
// 返回包装的对象
return it.getBean();
})
// 如果it.getBean();没有设置需要返回的对象,直接返回原始对象
.orElse(target);
}
// 获取操作时间,并给实体设置
private Optional<TemporalAccessor> touchDate(AuditableBeanWrapper<?> wrapper, boolean isNew) {
// 获取当前时间
Optional<TemporalAccessor> now = dateTimeProvider.getNow();
// 如果是新增,设置创建时间
now.filter(__ -> isNew).ifPresent(it -> wrapper.setCreatedDate(it));
// 如果是修改,修改,设置修改时间
now.filter(__ -> !isNew || modifyOnCreation).ifPresent(it -> wrapper.setLastModifiedDate(it));
return now;
}
// 获取AuditorAware返回的审计人,并给实体设置
private Optional<Object> touchAuditor(AuditableBeanWrapper<?> wrapper, boolean isNew) {
return auditorAware.map(it -> {
// 回调AuditorAware接口的getCurrentAuditor方法,获取对应的审计人
Optional<?> auditor = it.getCurrentAuditor();
// 如果是新增,设置创建人
auditor.filter(__ -> isNew).ifPresent(foo -> wrapper.setCreatedBy(foo));
// 如果是修改,设置最后修改人
auditor.filter(__ -> !isNew || modifyOnCreation).ifPresent(foo -> wrapper.setLastModifiedBy(foo));
return auditor;
});
}
}
// 处理实体持久化,更新前后的回调
@Configurable
public class AuditingEntityListener {
// AuditingHandler处理器
private ObjectFactory<AuditingHandler> handler;
// 在上面已经注册了AuditingHandler,这个时候已经将该属性设置了值
public void setAuditingHandler(ObjectFactory<AuditingHandler> auditingHandler) {
this.handler = auditingHandler;
}
// JPA规范中,实体持久化之前需要处理的逻辑
@PrePersist
public void touchForCreate(Object target) {
if (handler != null) {
// 获取到AuditingHandler真实对象,因为handler是一个ObjectFactory
AuditingHandler object = handler.getObject();
if (object != null) {
// 标记该类被创建了
object.markCreated(target);
}
}
}
// JPA规范中,实体更新之前需要处理的逻辑
@PreUpdate
public void touchForUpdate(Object target) {
if (handler != null) {
// 获取到AuditingHandler真实对象,因为handler是一个ObjectFactory
AuditingHandler object = handler.getObject();
if (object != null) {
// 标记该类被修改了
object.markModified(target);
}
}
}
}
// 是Spring AOP中的一个aspect(切面),它用于支持@Configurable注解,注意,不是@Configuration注解
// @Configurable这个注解允许你通过AOP来进行运行时的依赖注入
// 下列代码就表示标注了@Configurable类,在运行期间进行增强,会执行对应的通知,来手动对对普通对象进行Bean的配置
// 所以,只要标注了@Configurable的类,并且向Spring容器中注入这个AnnotationBeanConfigurerAspect
// 那么,就算你手动new对象,他也会帮你配置好这个对象,执行bean的依赖注入和初始化
// 其中AuditingEntityListener就是这样,你new出来看一下就明白
@Aspect
class AnnotationBeanConfigurerAspect {
// 用于支持Configuration处理
private BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport();
// 下面这些通知,就是根据不同的切点来配置自定义配置Bean的信息
@Before(value = "(beanConstruction(bean) && (preConstructionCondition() && inConfigurableBean()))",argNames = "bean")
public void ajc$before$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$1$e854fa65(Object bean) {
this.configureBean(bean);
}
@AfterReturning(pointcut = "(beanConstruction(bean) && (postConstructionCondition() && inConfigurableBean()))",returning = "",argNames = "bean")
public void ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(Object bean) {
this.configureBean(bean);
}
@AfterReturning(pointcut = "(beanDeserialization(bean) && inConfigurableBean())",returning = "",argNames = "bean")
public void ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$3$6aa27052(Object bean) {
this.configureBean(bean);
}
// 配置Bean的信息
public void configureBean(Object bean) {
this.beanConfigurerSupport.configureBean(bean);
}
// 设置
public void setBeanFactory(BeanFactory beanFactory) {
// 设置注解Bean连接信息解析器
this.beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
this.beanConfigurerSupport.setBeanFactory(beanFactory);
}
// 注释Bean连接信息解析器
static class AnnotationBeanWiringInfoResolver{
public BeanWiringInfo resolveWiringInfo(Object beanInstance) {
// 获取类中的@Configurable
Configurable annotation = beanInstance.getClass().getAnnotation(Configurable.class);
// 构建连接信息
return (annotation != null ? buildWiringInfo(beanInstance, annotation) : null);
}
// 构建连接信息
protected BeanWiringInfo buildWiringInfo(Object beanInstance, Configurable annotation) {
// 如果设置了注入方式
if (!Autowire.NO.equals(annotation.autowire())) {
return new BeanWiringInfo(annotation.autowire().value(), annotation.dependencyCheck());
}
// 如果设置了当前实例的bean的名称
else if (!annotation.value().isEmpty()) {
return new BeanWiringInfo(annotation.value(), false);
}
else {
// 获取当前实例的bean的名称
// getDefaultBeanName: return ClassUtils.getUserClass(beanInstance).getName();
return new BeanWiringInfo(getDefaultBeanName(beanInstance), true);
}
}
}
static class BeanConfigurerSupport{
// 手动执行配置Bean,让一个普通对象执行Bean的部分生命周期(自动注入,初始化)
public void configureBean(Object beanInstance) {
// 不存在beanFactory,不需要处理
if (this.beanFactory == null) {
return;
}
// 在AnnotationBeanConfigurerAspect中setBeanFactory设置了
AnnotationBeanWiringInfoResolver bwiResolver = this.beanWiringInfoResolver;
// 解析注解信息
BeanWiringInfo bwi = bwiResolver.resolveWiringInfo(beanInstance);
if (bwi == null) {
return;
}
ConfigurableListableBeanFactory beanFactory = this.beanFactory;
try {
// 获取注解中配置的beanName,如果没有配置,默认为实例的名称
String beanName = bwi.getBeanName();
// if和else都是在对一个new出来的对象进行自动注入,初始化操作
// 就是如果容器中存在这个bean和不存在有一点配置需要做
if (bwi.indicatesAutowiring() || (bwi.isDefaultBeanName() && beanName != null && !beanFactory.containsBean(beanName))) {
beanFactory.autowireBeanProperties(beanInstance, bwi.getAutowireMode(), bwi.getDependencyCheck());
beanFactory.initializeBean(beanInstance, (beanName != null ? beanName : ""));
}
else {
beanFactory.configureBean(beanInstance, (beanName != null ? beanName : ""));
}
}
catch (BeanCreationException ex) {
throw ex;
}
}
}
}
SpringDataJPA开启审计的实现原理总结
最新推荐文章于 2024-06-24 09:24:30 发布