如何截获自己创建实例的JdbcTemplate

问题描述 投票:0回答:2

我想做的是在对当前会话执行的任何DQL(“ SELECT ...”)或DML(INSERT / UPDATE / DELETE ...)之后收集数据库统计值。当前,我已经利用Spring AOP实现此目标,如下所示:

@Aspect
@Component
public class StatisticalValueCollector {
    @After("execution(* org.springframework.jdbc.core..*JdbcOperations.*(String, ..))")
    public void collectStatisTicalValues(JoinPoint jp) {
        //Collect DB statistical values
    }
 }

它对JdbcTemplateNamedParameterJdbcTemplate以及@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: Able to Intercept JDBCTemplate calls but not NamedParameterJdbcTemplate calls 进行代理。

因此,我的问题是“ 如何截取自己创建的JdbcTemplateNamedParameterJdbcTemplate”;任何意见和建议将不胜感激。谢谢!

java spring spring-boot aop jdbctemplate
2个回答
0
投票

在带有@Configuration注释的类中,将JdbcTemplate定义为@Bean

@Configuration
public class JdbcConfiguration {

    private DriverManagerDatasource ds = new DriverManagerDatasource();

    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(ds);
    }
}

这样,通过将@Aspect bean放入JdbcTemplate,可以使Spring在AOP中拦截AOP时使用AOP代理它。您现在可以通过以下方式自动接线:

ApplicationContext

0
投票

如果在两种情况下都以这种方式打印JDBC模板实例,则>]

@Autowired private JdbcTemplate jdbcTemplate;

然后您将看到自己创建的那个

System.out.println(jdbcTemplate + "\n  " + jdbcTemplate.getClass());

同时您会看到自动注射的>]

org.springframework.jdbc.core.JdbcTemplate@3c71cf3e
  class org.springframework.jdbc.core.JdbcTemplate

发现差异?对于后者,如果存在针对它的方面,Spring会创建一个动态代理。仅当存在动态代理时,Spring AOP才能在其上注册方面建议。

我不是Spring用户,所以我不知道是否存在另一种规范的方式来创建JDBC模板,并根据需要自动为其创建动态代理。因此,除非您要手动创建代理(这是可能的,但不必要的复杂操作)或找到另一种方法,否则请使用依赖项注入(DI)和自动装配。那不是一开始就使用Spring的全部目的吗?创建可以注入的依赖关系对于像Spring这样的DI容器来说是一种反模式。

如果坚持非正统且难以测试(如何为调用构造函数的局部变量注入模拟?)方法,则始终可以将完整的AspectJ用作Spring AOP的替代方法。但我怀疑在这种情况下是否值得。

© www.soinside.com 2019 - 2024. All rights reserved.