【问题标题】:Spring AOP Aspect used in JdbcOperations not invoked未调用 JdbcOperations 中使用的 Spring AOP 方面
【发布时间】:2017-02-16 18:07:21
【问题描述】:

我想做这样的事情http://www.gotoquiz.com/web-coding/programming/java-programming/log-sql-statements-with-parameter-values-filled-in-spring-jdbc/

我有一个 Spring MVC 项目,我正在使用 Spring 4.3.0.RELEASE。

我正在为我的所有 DAOS 使用通用抽象类

public abstract class GenericDaoImpl {
    @Autowired
    protected JdbcTemplate jdbcTemplate;
}


@Repository
public class UserDAOImpl extends GenericDaoImpl implements UserDAO{

}

jdbcTemplate 在我的 auto-config.xml 中定义

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${db.driver}" />
    <property name="url" value="${db.url}" />
    <property name="username" value="${db.user}" />
    <property name="password" value="${db.password}" />
</bean>

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"/>
</bean>

为了实现更接近该指南中的内容,我有

将这些依赖项添加到我的 pom.xml 中:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>4.3.0.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.9</version>
</dependency>

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.9</version>
</dependency>

我已将 @EnableAspectJAutoProxy 添加到 @Configuration 类中。

我的观点是:

@Aspect
@Component
public class SqlParametersLogger {

    private final Logger logger = LoggerFactory.getLogger(SqlParametersLogger.class);

    @Before("execution(* org.springframework.jdbc.core.JdbcOperations.*(..))")
    public void log(JoinPoint jp) {
        logger.info("Hello?");
    }
}

我的 Aspect 函数永远不会被调用。我已经用我的服务层的切入点尝试了这个方面,它可以工作。但是使用 JdbcOperations 就不行了。

有什么想法吗?

【问题讨论】:

    标签: java spring aspectj spring-aop spring-jdbc


    【解决方案1】:

    您的 aop 表达式被定义为 JdbcOperation.* 的切入点,它是一个接口,不建议调用接口。

    AspectJ 可以在 spring 框架中为 spring-managed-beans 截取切入点。 如果 bean 不是 spring 管理的,您需要使用 ProxyFactoryBean/ProxyFactory 手动注册它以获取建议。在您的情况下,您已经有一个实现 JdbcOperations 接口的 bean,该接口注册在您的 spring application-context 中。

    根据您的问题,将切入点更改为使用 JdbcOperations 接口的任何实现(jdbcTemplate bean 定义)应该可以解决您的问题。

    例如

    @Before("execution(* org.springframework.jdbc.core.JdbcOperations+.*(..))")
    

    【讨论】:

    • 感谢您的回复@Alex。我已将 @Before("execution(* org.springframework.jdbc.core.JdbcOperations.* (..))") 更改为 @Before("execution(* org.springframework.jdbc.core.JdbcOperations+.*(..))") 但仍然没有调用 Aspect。
    • 我什至尝试将其直接设置为@Before("execution(* org.springframework.jdbc.core.JdbcTemplate.*(..))"),但也没有调用Aspect
    【解决方案2】:

    你在表达式中丢失了 1 个.*,应该是

    // this works fine 
    @Before("execution(* org.springframework.jdbc.core..*JdbcOperations.*(String, ..))") 
    

    但是你写的很像

    // this's not good 
    @Before("execution(* org.springframework.jdbc.core.JdbcOperations.*(..))") 
    

    当我看到这个时,这个答案突然出现了,链接在这里https://stackoverflow.com/questions/58282255/how-to-intercept-jdbctemplate-whose-instance-is-created-by-myself

    【讨论】:

      猜你喜欢
      • 2017-12-26
      • 1970-01-01
      • 1970-01-01
      • 2011-09-20
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多