Spring AOP with Generics:AfterReturning两次

时间:2016-11-21 19:02:42

标签: java spring generics spring-aop

我试图拦截一个函数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,这是一个抽象类,我认为它是导致双重执行的那个....

我走得太远,只是在某个地方错过了一个简单的配置?

0 个答案:

没有答案