如何子类化Spring LDAP事务管理器实现事务开始审计?
解决方案:两种方式实现LDAP事务开始时的审计操作
针对你的需求,不需要子类化ContextSourceAndHibernateTransactionManager也能实现事务开始阶段的审计,当然如果需要更精确的控制,也可以通过自定义配置来实现。下面分两种方案详细说明:
方案一:使用Spring事务监听器(推荐,代码更简洁)
Spring从4.2版本开始提供了事务事件监听机制,你可以通过@TransactionalEventListener注解监听事务启动事件,刚好对应你需要的doBegin阶段(事务启动后、业务代码执行前触发),完全满足少量审计代码的需求。
实现步骤:
- 创建一个监听器类,标记为Spring组件,然后编写监听事务启动事件的方法:
@Component public class LdapTransactionAuditListener { // 监听事务启动事件 @TransactionalEventListener public void auditTransactionStart(TransactionStartedEvent event) { // 这里编写你的审计逻辑,比如记录事务信息、当前操作人等 TransactionStatus status = event.getTransactionStatus(); String transactionName = status.getTransaction().getName(); boolean isReadOnly = status.isReadOnly(); // 示例:打印审计信息(实际可替换为日志入库、审计表插入等操作) System.out.println("LDAP事务已启动:名称=" + transactionName + ",是否只读=" + isReadOnly); } }
- 确保你的Spring上下文已经开启事务管理:如果是XML配置,你已经有
<ldap:transaction-manager>和<tx:annotation-driven/>(通常会配套配置);如果是Java配置,已经有@EnableTransactionManagement注解,这一步一般不需要额外操作。
这种方式的优势是不需要修改原有事务管理器的配置,代码侵入性极低,适合只需要在事务开始时执行少量代码的场景。
方案二:自定义事务管理器(精确控制doBegin时机)
如果你的审计逻辑需要严格在doBegin方法执行前后触发,或者需要修改事务启动的逻辑,可以通过自定义事务管理器实现。由于<ldap:transaction-manager>标签不支持直接指定自定义子类,你可以改用Java配置或者手动XML配置来定义事务管理器:
Java配置示例:
@Configuration public class LdapTransactionConfig { @Autowired private SessionFactory sessionFactory; @Autowired private ContextSource contextSource; // 自定义LDAP事务管理器Bean @Bean(name = "ldapTransactionManager") public PlatformTransactionManager ldapTransactionManager() { return new CustomLdapTransactionManager(contextSource, sessionFactory); } // 继承ContextSourceAndHibernateTransactionManager并重写doBegin方法 private static class CustomLdapTransactionManager extends ContextSourceAndHibernateTransactionManager { public CustomLdapTransactionManager(ContextSource contextSource, SessionFactory sessionFactory) { super(contextSource, sessionFactory); // 配置默认重命名策略,对应原XML中的<ldap:default-renaming-strategy/> setDefaultRenamingStrategy(new DefaultRenamingStrategy()); } @Override protected void doBegin(Object transaction, TransactionDefinition definition) { // 先执行你的审计逻辑 performTransactionAudit(definition); // 再调用父类的doBegin方法完成事务启动 super.doBegin(transaction, definition); } private void performTransactionAudit(TransactionDefinition definition) { // 这里编写你的审计操作 String txName = definition.getName(); int propagation = definition.getPropagationBehavior(); // 示例:记录事务传播行为、超时时间等信息 } } }
XML配置替代方案(如果坚持用XML):
你可以放弃<ldap:transaction-manager>标签,手动配置自定义事务管理器Bean:
<bean id="ldapTransactionManager" class="com.yourpackage.CustomLdapTransactionManager"> <constructor-arg ref="contextSource"/> <constructor-arg ref="sessionFactory"/> <property name="defaultRenamingStrategy"> <bean class="org.springframework.ldap.transaction.compensating.DefaultRenamingStrategy"/> </property> </bean>
这种方式的优势是能完全控制doBegin方法的执行顺序,适合需要深度定制事务启动逻辑的场景。
内容的提问来源于stack exchange,提问作者Entropy
相关产品推荐
相关产品推荐

