我想要做的是在对当前会话执行的任何DQL(“ SELECT ...”)或DML(INSERT / UPDATE / DELETE ...)之后收集DB统计值。 当前,我已经利用Spring AOP实现了以下目标:
@Aspect @Component public class StatisticalValueCollector { @After("execution(* org.springframework.jdbc.core..JdbcOperations.(String, ..))") public void collectStatisTicalValues(JoinPoint jp) { //Collect DB statistical values } } 它的工作原理perfectlly两者JdbcTemplate并NamedParameterJdbcTemplate通过注释的@Autowired,但是当我自己创建它们的实例ㄋ ,这是行不通的。
工作示例:
@Autowired JdbcTemplate jdbcTemplate; ... List<Map<String, Object>> result = jdbcTemplate.queryForList("SELECT ..."); 无效的示例:
DriverManagerDatasource ds = new DriverManagerDatasource(); ... JdbcTemplate jdbcTemplate = new JdbcTemplate (ds); List<Map<String, Object>> result = jdbcTemplate.queryForList("SELECT ..."); 据我所知,如果似乎JdbcTemplate是由Spring创建的,则可以根据此后AOP进行代理:可以拦截JDBCTemplate调用,但不能拦截NamedParameterJdbcTemplate调用 。
因此,我的问题是“ 如何自己拦截JdbcTemplate或NamedParameterJdbcTemplate创建? ”; 任何意见和建议将不胜感激。谢谢!
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
要解决您遇到的问题,即在自行创建JdbcTemplate
或NamedParameterJdbcTemplate
实例时也能应用Spring AOP进行拦截,您可以考虑以下几种方法:
一个直接的解决方案是通过Spring的Bean工厂方法来创建这些实例,这样它们就会被Spring管理并自动代理。例如:
@Configuration
public class AppConfig {
@Autowired
private DataSource dataSource;
@Bean
public JdbcTemplate jdbcTemplate() {
return new JdbcTemplate(dataSource);
}
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
return new NamedParameterJdbcTemplate(dataSource);
}
}
然后在您的服务类中,通过@Autowired
注入这些Bean,这样AOP切面就能正常工作了。
如果您有特殊需求必须手动创建实例,可以使用Spring的ProxyFactoryBean
来手动创建代理对象,这样即使手动实例化,也能应用AOP逻辑。
@Bean
public ProxyFactoryBean jdbcTemplateProxy() {
ProxyFactoryBean factory = new ProxyFactoryBean();
factory.setTarget(new JdbcTemplate(dataSource));
factory.addAdvice(new StatisticalValueInterceptor()); // 自定义拦截器实现统计收集
factory.setInterfaces(JdbcTemplate.class);
return factory;
}
// 类似地为NamedParameterJdbcTemplate创建代理
这里,您需要实现一个自定义拦截器(如StatisticalValueInterceptor
),它应该扩展自MethodInterceptor
接口,并在其中实现统计值收集的逻辑。
如果上述方案不适用,且您确实需要在运行时动态地对非Spring管理的对象应用切面,那么可能需要探索更底层的手动编织技术。这通常涉及到使用AspectJ的load-time weaving (LTW) 或 compile-time weaving (CTW),但这会增加复杂度,并可能引入额外的依赖和配置。
最推荐的方法是尽量让Spring容器管理所有需要被AOP切面影响的Bean,如方法1所示。这不仅简化了配置,也保持了代码的清晰和一致性。只有在特定场景下,才考虑采用更复杂的方案,如手动编织或使用ProxyFactoryBean
。