весенний аспект не запускается на 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 (..))


person lives    schedule 15.05.2018    source источник
comment
С помощью Spring AOP вы можете рекомендовать только компоненты, управляемые Spring. Являются ли ваши DataSource экземпляры управляемыми компонентами Spring?   -  person Nándor Előd Fekete    schedule 15.05.2018
comment
javax.sql.DataSource не управляется Spring. Я использую Spring с репозиториями jpa. Соединение получается из пула соединений tomcat.   -  person lives    schedule 16.05.2018


Ответы (1)


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

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

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

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

person Nándor Előd Fekete    schedule 16.05.2018
comment
Я попытался добавить приведенный выше фрагмент для DelegatingDataSource .. но во время запуска приложения я получаю BeanCurrentlyInCreationException. Пожалуйста, помогите мне разрешить эту ошибку. - person Karthikeyan; 30.07.2020
comment
ErrorStackTrace :: org.springframework.beans.factory.BeanCurrentlyInCreationException: Ошибка при создании bean-компонента с именем 'dataSource': запрошенный bean-компонент в настоящее время находится в процессе создания: существует ли неразрешимая циклическая ссылка? - person Karthikeyan; 30.07.2020
comment
@Karthikeyan да, я думаю, у вас проблема с круговой зависимостью. Решите это и попробуйте снова. - person Nándor Előd Fekete; 30.07.2020