我试图拦截一个函数save,以便创建它的历史记录,但是方面被调用了两次。
我会首先向您展示代码,然后向您解释我的调试分析......
所以我得到了一个FunctionServiceSupport,其定义如下:
@Named
@Qualifier("functionService")
public class FonctionServiceSupport extends BaseServiceSupport<FunctionDTO, Function> {}
public abstract class BaseServiceSupport<T extends BaseDTO, E extends BaseEntity> implements BaseService<T> {
@Inject
protected BaseRepository<E> baseRepository;
@Inject
protected BaseMapper<T, E> mapper;
@Override
public T save(T dto) {
E entity = mapper.dtoToEntity(dto);
entity = baseRepository.save(entity);
return mapper.entityToDto(entity);
}
}
我的DTO:
public class FunctionDTO extends BaseDTO {}
public abstract class BaseDTO {}
然后我的方面:
@Aspect
@Named
public class HistoryFunctionServiceSupport extends HistoryBaseServiceSupport<FunctionDTO, FunctionHistory> {
@Override
@AfterReturning(
pointcut="execution(* x.y.z.services.BaseService+.save(*))",
returning="dto")
public void addNewHistorisyEntry(FunctionDTO dto) {
super.addNewHistorisyEntry(dto);
}
}
public abstract class HistoryBaseServiceSupport<D extends BaseDTO, E extends BaseEntityHistory> implements HistoryBaseService<D> {
@Inject
protected BaseHistoryMapper<E, D> historyMapper;
@Inject
protected BaseHistoryRepository<E> historyRepository;
@Override
public void addNewHistorisyEntry(D dto) {
E historyEntity = historyMapper.entityDtoToEntityHistory(dto);
historyRepository.save(historyEntity);
}
}
因此,在FunctionServiceSupport上运行save方法会导致@AfterReturning建议被调用两次。
对org.springframework.aop.framework.DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
method
参数获取值:
public abstract x.y.z.dto.BaseDTO x.y.z.services.BaseService.save(x.y.z.dto.BaseDTO)
targetClass
参数:class x.y.z.services.FunctionServiceSupport
并生成两个建议拦截器:
[
org.springframework.aop.interceptor.ExposeInvocationInterceptor@7f31e4ab,
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor@2a5fd98f,
org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor@7ac45104
]
第一个AfterReturningAdviceInterceptor详述如下:
org.springframework.aop.aspectj.AspectJAfterReturningAdvice:
advice method [
public void x.y.z.services.HistoryFunctionServiceSupport.addNewHistoryEntry(x.y.z.dto.BaseDTO)];
aspect name 'historyFunctionServiceSupport'
第二个是:
org.springframework.aop.aspectj.AspectJAfterReturningAdvice:
advice method [
public void x.y.z.services.HistoryFunctionServiceSupport.addNewHistoryEntry(x.y.z.dto.FunctionDTO)];
aspect name 'historyFunctionServiceSupport'
我看到它生成了两个具有FunctionDTO
的建议拦截器,这似乎完全没问题。
但另一个是BaseDTO
,这是一个抽象类,我认为它是导致双重执行的那个....
我走得太远,只是在某个地方错过了一个简单的配置?