首页 > 解决方案 > 弹簧方面没有在 getConnection 上被解雇

问题描述

我试图在 spring 3.2.3 中拦截 getConnection 调用

@Component
@Aspect
@Order(value = 1)
public class ConnectionAspect {

    //@AfterReturning(pointcut = "execution(java.sql.Connection javax.sql.DataSource.getConnection(..))", returning = "connection")
    @Around("execution(java.sql.Connection javax.sql.DataSource.getConnection(..))")
    public Connection prepare(ProceedingJoinPoint pjp) throws Throwable {
        return MyConnectionProxy.newInstance((Connection) pjp.proceed(pjp.getArgs()));
    }

}

调用 getConnection 时不会调用此方面。切入点定义执行是否有错误(java.sql.Connection javax.sql.DataSource.getConnection(..))

标签: springaopaspectjspring-aopspring-aspects

解决方案


Spring AOP 只能建议 Spring 托管的 bean。如果您的DataSource实例不是 Spring 托管的 bean,您将无法使用 Spring AOP 实现您的目标。

我会尝试通过围绕容器提供的数据源创建某种委托代理来解决这个问题,并使其成为由 spring 管理的 bean。事实证明,Spring 中实际上有一个专门用于此目的的类。它被称为DelegatingDataSource。您只需要对此类进行子类化,覆盖该getConnection()方法(或您需要影响的任何其他方法的行为),将其设置为委托给提供的容器DataSource,并使其成为 Spring 托管 bean,您就可以开始了。

沿着这个例子做一些事情应该这样做:

@Configuration
public class DataSourceConfiguration {

    public static class MySpecialDataSource extends DelegatingDataSource {

        public MySpecialDataSource(DataSource delegate) {
            super(delegate);
        }

        @Override
        public Connection getConnection() throws SQLException {
            return super.getConnection();
        }
    }

    @Bean
    public DataSource dataSource(@Autowired DataSource containerDataSource) {
        return new MySpecialDataSource(containerDataSource);
    }

    @Bean(name="containerDataSource")
    public JndiObjectFactoryBean containerDataSource() {
        JndiObjectFactoryBean factoryBean = new JndiObjectFactoryBean();
        factoryBean.setJndiName("jdbc/MyDataSource");
        return factoryBean;
    }

}

最好的是,您甚至不需要 Spring AOP 或 AspectJ。


推荐阅读