SpringDataJPA开启审计的实现原理总结

@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;
            }
        }
    }
}

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值