1
votes

I am working on one component to achieve audit using Spring AOP. I could use it for most of the service's methods. But found that with Mybatis mappers AOP point-cuts don't work.

Basically, Spring AOP only works with Spring-managed beans. But these mapper beans have been scanned using mybatis.spring.*.MapperScan and can be autowired in other Spring components.

Why can these beans not be scanned for Spring AOP? Any idea?

I can use AspectJ but was keen to find out how mybatis.spring.*.MapperScan works.

for example -

I have these configurations one for Mybatis mapper scan and other config for application specific configurations.

@Configuration
@MapperScan("com.test.mapper")
public class ProviderConfiguration {

   @Bean
   public SqlSessionFactory sqlSessionFactory(final DataSource src) throws Exception {
      ...
   }
}

@Configuration
@EnableAspectJAutoProxy
public class MainConfiguration {

}

My Dao logic where i call mapper method -

@Component
public class TestDao {

   //injecting mybatis mapper here
   @Inject
   private SaveTableData saveTableData;

   public TableData save(TableData tableData) {
       saveTableData.updateTableData(tableData);
   }
}

I have registered my pointcuts as below

@Component
@Aspect
public class TestAdvices {
  @Pointcut("execution(* com.test.mapper.SaveTableData.updateTableData(*))") 
  public void commonSaveTableData(TableData tableData) {
  }

  @Pointcut("execution(* com.test.service.CreateTableData.createTableData(*))") 
  public void commonCreateTableData(TableData tableData) {
  }  

  //advices
  @After("commonSaveTableData(tableData)")
  public void addHistoryWhenSaveTableData(TableData tableData) throws Throwable {
      //do stuff    
  }

  //advices
  @After("commonCreateTableData(tableData)")
  public void addHistoryWhenCreateTableData(TableData tableData) throws Throwable {
      //do stuff    
  }
}

Issue is commonCreateTableData which is on service method works as expected. But commonSaveTableData which is on Mybatis mapper method does't get invoke.

Question is if i can autowire these Mappers in any Spring bean why can't Spring AOP intercept method call using these pointcuts?

2
I have updated the question with the example.Amit Naik
Can you add the Service Code - or wherever you make the call to the mapper?Reg
its fairly simple call from my Dao class. i have updated it.Amit Naik
Everything in the configuration looks good so far. Can you also show advices associated with the defined pointcuts?Roman Konoval
Have added sample implementation for advices but it does not even get invoke with mapper mathodsAmit Naik

2 Answers

0
votes

I think your pointcut expression is not correct, try this

@Component
@Aspect
public class TestAdvices {
  @Pointcut("execution(* com.test.mapper.SaveTableData.updateTableData(*)) && args(tableData)", argNames="tableData") 
  public void commonSaveTableData(TableData tableData) {
  }



//advices
  @After("commonSaveTableData(tableData)", argNames="tableData")
  public void addHistoryWhenSaveTableData(TableData tableData) throws Throwable {
      //do stuff    
  }
//...
}
0
votes

The reason you can't cut into the mapper like this is that when mapper is scanned by mybatis, it's bean definition has bean changed in a way that its interface is still the mapper interface but its class has been changed to MapperFactoryBean