Весенний аспект не срабатывает на 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 для этого.