0

I am trying to intercept the getConnection call in spring 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()));
    }

}

This aspect does not invoked on calling getConnection . Is there any mistake in the point cut definition execution(java.sql.Connection javax.sql.DataSource.getConnection(..))

lives
  • 1,243
  • 5
  • 25
  • 61
  • 1
    With Spring AOP you can only advise spring managed beans. Are your `DataSource` instances spring managed beans? – Nándor Előd Fekete May 15 '18 at 18:26
  • javax.sql.DataSource is not spring managed .I am using spring with jpa repositories . The connection is obtained from the tomcat connection pool. – lives May 16 '18 at 06:26

1 Answers1

0

Spring AOP can only advise spring managed beans. If your DataSource instances are not spring managed beans, you won't be able to achieve your goal with Spring AOP.

I would try to solve this issue by creating some kind of delegating proxy around the container provided DataSource, and make it a bean managed by spring. It turns out there's actually a class intended in Spring specifically for this purpose. It's called DelegatingDataSource. You only need to subclass this class, ovverride the getConnection() method (or whichever other method's behavior you need to affect), set it up for delegating to the container provided DataSource, and making it a spring managed bean and you're good to go.

Someting along this example should do it:

@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;
    }

}

The best thing is that you didn't even need Spring AOP or AspectJ for that.

Nándor Előd Fekete
  • 6,988
  • 1
  • 22
  • 47
  • I tried to add above snippet for "DelegatingDataSource".. but during application startup - i am getting BeanCurrentlyInCreationException. Please help me resolve this error. – Karthikeyan Jul 30 '20 at 06:57
  • ErrorStackTrace:: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dataSource': Requested bean is currently in creation: Is there an unresolvable circular reference? – Karthikeyan Jul 30 '20 at 06:57
  • @Karthikeyan yes, I think you have a circular dependency problem. Solve that and try again. – Nándor Előd Fekete Jul 30 '20 at 14:12