Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何拦截自己创建实例的JdbcTemplate_Java_Spring_Spring Boot_Aop_Jdbctemplate - Fatal编程技术网

Java 如何拦截自己创建实例的JdbcTemplate

Java 如何拦截自己创建实例的JdbcTemplate,java,spring,spring-boot,aop,jdbctemplate,Java,Spring,Spring Boot,Aop,Jdbctemplate,我要做的是在为当前会话执行的任何DQL(“选择…”)或DML(插入/更新/删除…)之后收集DB统计值。 目前,我已利用Spring AOP实现以下目标: @Aspect @Component public class StatisticalValueCollector { @After("execution(* org.springframework.jdbc.core..*JdbcOperations.*(String, ..))") public void collectSt

我要做的是在为当前会话执行的任何DQL(“选择…”)或DML(插入/更新/删除…)之后收集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
    }
 }
它对
@Autowired
注释的
JdbcTemplate
NamedParameterJdbcTemplate
都非常有效,但是当我创建它们的实例时ㄋ 就我个人而言,它不起作用

工作示例:

@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 ...");
@Autowired
jdbc模板jdbc模板;
...
列表结果=jdbcTemplate.queryForList(“选择…”);
未工作示例:

@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 ...");
DriverManager数据源ds=new DriverManager数据源();
...
JdbcTemplate JdbcTemplate=新的JdbcTemplate(ds);
列表结果=jdbcTemplate.queryForList(“选择…”);
据我所知,如果
JdbcTemplate
是由Spring创建的,那么它可以根据本文进行代理

因此,我的问题是“如何拦截我自己创建的
JdbcTemplate
NamedParameterJdbcTemplate

如有任何意见和建议,将不胜感激。谢谢

更新

我还调查了不同的方法,如和,似乎唯一的解决方案是使用纯AspectJ或其他什么?

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

@Configuration
public class JdbcConfiguration {

    private DriverManagerDatasource ds = new DriverManagerDatasource();

    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(ds);
    }
}
这样,通过将
JdbcTemplate
bean放入
ApplicationContext
中,可以使Spring在拦截
@Aspect
时使用AOP代理它。现在,您可以使用以下工具自动关联:

@Autowired private JdbcTemplate jdbcTemplate;

如果在这两种情况下都像这样打印JDBC模板实例

System.out.println(jdbcTemplate+“\n”+jdbcTemplate.getClass());
然后,对于你自己创造的,你会看到

org.springframework.jdbc.core。JdbcTemplate@3c71cf3e
类org.springframework.jdbc.core.jdbc模板
而对于自动注入式,您将看到

org.springframework.jdbc.core。JdbcTemplate@8f39224
类org.springframework.jdbc.core.JdbcTemplate$$EnhancerBySpringCGLIB$$59a5407f
找出区别了吗?对于后者,如果存在针对它的方面,Spring将创建一个动态代理。只有当存在一个动态代理时,SpringAOP才能注册它的方面建议

我不是Spring用户,所以我不知道是否有另一种创建JDBC模板的规范方法,可以根据需要自动为其创建动态代理。因此,除非您想手动创建代理(这是可能的,但不必要地复杂)或找到其他方法,否则只需使用依赖注入(DI)和自动连接。这不是使用Spring的最初目的吗?对于像Spring这样的DI容器来说,创建可以注入的依赖项是一种反模式


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

当然,但问题是如何将AOP与未自动连接的JDBC模板结合使用。不能将AOP用于使用
新建
创建的实例。我刚刚给了你一种截取
JdbcTemplate
方法的方法,让它成为Spring管理的
@Bean
@kriagaex,你可能在错误的答案下发布了它。谢谢你的回复!我知道我不能用Spring AOP代理Spring创建的对象。所以我会考虑你的建议。你好。你问了一个问题,我回答了。所以,请检查我的答案,然后接受+upvote,如果你认为它是正确的(我当然会)。