com.sun.proxy.$在jdbcTemplate上创建切入点时出现代理错误

SKa*_*aul 5 proxy spring aspectj spring-mvc spring-aop

我尝试进行切入点,以记录SQL查询

  @Before("execution(* org.springframework.jdbc.core.JdbcTemplate.*(String, ..))")
public void logSQLQueries() {
        System.out.println("@@");
    }
Run Code Online (Sandbox Code Playgroud)

我想在这里实现代码; http://www.gotoquiz.com/web-coding/programming/java-programming/log-sql-statements-with-parameter-values-filled-in-spring-jdbc/

但我明白了

java.lang.IllegalArgumentException: Can not set org.springframework.jdbc.core.JdbcTemplate field com.xyz.abc.dao.ABCDaoImpl.jdbcTemplate to com.sun.proxy.$Proxy53
Run Code Online (Sandbox Code Playgroud)

我在我的*-servlet.xml中创建了jdbcTemplate bean,并在我所有的DAO中自动启用了它.工作得非常好,但添加切入点会产生异常.有任何想法吗 ??

M. *_*num 8

默认情况下,Spring使用JDK动态代理来应用AOP.(有关代理的更多信息,请参见此处).

发生的事情是创建一个动态类(com.sun.proxy.$Proxy53),它实现目标类实现的所有接口.对于JdbcTemplate那是JdbcOperationsInitializingBean.所以动态类是a JdbcOperations但不是a JdbcTemplate,因此注入失败.

你有几个解决方案

  1. 使用接口JdbcOperations而不是类JdbcTemplate来编程
  2. 使用基于类的代理
  3. 使用加载时间编织

现在选项1和2是最简单的,而选项3是最强大和最复杂的开始(参见下面的链接).

为你班上的1改变

@Autowired
private JdbcTemplate jdbcTemplate;
Run Code Online (Sandbox Code Playgroud)

@Autowired
private JdbcOperations jdbcTemplate; 
Run Code Online (Sandbox Code Playgroud)

如果你正在扩展JdbcDaoSupport你可能会在泡菜中然后它将无法正常工作.

选项2,假设您已将属性<aop:aspectj-autoproxy />设置proxy-target-classtrue.这将需要cglib并将创建基于类的代理而不是基于接口的代理.

对于选项3,我参考参考指南,因为它涉及(可能)一个java-agent,并且可能有点复杂的工作.

链接

  1. 了解AOP代理
  2. 使用AspectJ进行加载时编织