Весенний аспект не срабатывает на getConnection

Я пытаюсь перехватить вызов getConnection весной 3.2.3

@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(..))

1 ответ

Spring AOP может посоветовать только бобы, управляемые весной Если твой DataSource экземпляры не являются bean-компонентами, управляемыми Spring, вы не сможете достичь своей цели с помощью Spring AOP.

Я попытался бы решить эту проблему, создав своего рода делегирование прокси вокруг контейнера, предоставленного DataSource, и сделав его компонентом, управляемым весной. Оказывается, есть класс, специально предназначенный для Spring специально для этой цели. Это называется DelegatingDataSource, Вам нужно только создать подкласс этого класса, переопределить getConnection() метод (или поведение любого другого метода, на которое вы должны повлиять), установите его для делегирования предоставленному контейнеру DataSource и сделав его бобом с пружинным управлением, и все готово.

Что-то в этом примере должно сделать это:

@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 для этого.

Другие вопросы по тегам