如何创建Spring托管的StatementInspector以支持SpringBoot特性?
实现Spring托管的Hibernate StatementInspector
问题原因
直接通过spring.jpa.properties配置statement_inspector时,Hibernate会自行通过反射实例化指定类,该实例不受Spring容器管理,因此无法使用@Autowired注入Bean、@Value读取配置属性等Spring特性。
解决方案
1. 编写Spring托管的StatementInspector类
给自定义Inspector添加@Component注解,让Spring接管实例化,即可正常使用Spring的依赖注入功能:
import org.hibernate.resource.jdbc.spi.StatementInspector; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class SqlStatementInspector implements StatementInspector { @Value("${custom.sql.inspect.enabled}") private boolean inspectEnabled; // 示例:注入其他Spring Bean // @Autowired // private SqlLogService sqlLogService; @Override public String inspect(String sql) { if (inspectEnabled) { // 自定义SQL处理逻辑,比如日志打印、SQL修改等 System.out.println("执行SQL: " + sql); // sqlLogService.recordSql(sql); } return sql; } }
2. 配置Hibernate使用Spring托管的Inspector
通过HibernatePropertiesCustomizer将Spring托管的Inspector实例传递给Hibernate,替代原来的配置属性方式:
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class HibernateConfig { private final SqlStatementInspector sqlStatementInspector; // 构造注入Spring托管的Inspector实例 public HibernateConfig(SqlStatementInspector sqlStatementInspector) { this.sqlStatementInspector = sqlStatementInspector; } @Bean public HibernatePropertiesCustomizer hibernatePropertiesCustomizer() { return properties -> properties.put( "hibernate.session_factory.statement_inspector", sqlStatementInspector ); } }
替代方案:直接配置EntityManagerFactory
如果需要更精细控制JPA配置,也可以通过LocalContainerEntityManagerFactoryBean直接设置Inspector:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import javax.sql.DataSource; @Configuration public class HibernateConfig { private final DataSource dataSource; private final SqlStatementInspector sqlStatementInspector; public HibernateConfig(DataSource dataSource, SqlStatementInspector sqlStatementInspector) { this.dataSource = dataSource; this.sqlStatementInspector = sqlStatementInspector; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource); em.setPackagesToScan("com.your.entity.package"); // 替换为你的实体类包路径 HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); // 设置Spring托管的StatementInspector em.getJpaPropertyMap().put( "hibernate.session_factory.statement_inspector", sqlStatementInspector ); return em; } }
内容的提问来源于stack exchange,提问作者CDO
相关产品推荐
相关产品推荐

