我试图在春季3.2.3中拦截getConnection调用
@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(..))
Spring AOP只能建议Spring托管bean。如果您的DataSource
实例不是Spring托管bean,那么您将无法通过Spring AOP实现目标。
我会尝试通过在容器提供的DataSource周围创建某种委托代理来解决这个问题,并使其成为由spring管理的bean。事实证明,实际上有一个专门用于此目的的Spring类。它被称为DelegatingDataSource
。你只需要继承这个类,ovverride getConnection()
方法(或者你需要影响的其他方法的行为),设置它以委托给DataSource
提供的容器,并使它成为一个Spring托管bean,你很高兴。
这个例子应该做的事情:
@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。