весенний аспект не срабатывает на getConnection - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь перехватить вызов 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 Ответ

0 голосов
/ 16 мая 2018

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

...