AOP内部调用失效-解决方法
问题描述
既然内部调用无法触发,我们需要获取到bean去调用,如果直接在 DemoServiceImpl内定义 IDemoService 会因为循环引用无法启动。
所以我们需要直接从容器获取bean,而Spring提供了获取自身bean代理的方法 AopContext.currentProxy():
/**
 * 测试Demo service impl
 *
 * @author azhuzhu 2021/7/11 14:20.
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DemoServiceImpl implements IDemoService {
    private final DemoRepository demoRepository;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertDemo(Demo demo) {
        demoRepository.insert(demo);
        throw new RuntimeException();
    }
    @Override
    public void doSomething() {
        ((IDemoService)AopContext.currentProxy()).insertDemo(new Demo());
    }
}
优雅的解决
如果项目上经常用到内部调用的AOP触发,我们可以更优雅一点,定义一个统一的接口:
/**
 * 通用自身代理获取
 *
 * @author azhuzhu 2020/7/11 14:40.
 */
public interface AopProxy<T> {
    @SuppressWarnings("unchecked")
    default T self() {
        return (T) AopContext.currentProxy();
    }
}
需要用到内部调用AOP的,接口继承 AopProxy<T> :
/**
 * 测试服务
 *
 * @author azhuzhu 2020/7/11 14:19.
 */
public interface IDemoService extends AopProxy<IDemoService> {
    /**
     * AOP事务处理插入数据
     * 
     * @param demo 测试数据
     */
    void insertDemo(Demo demo);
    /**
     * 内部调用测试插入数据
     */
    void doSomething();
}
实现方法调用 self() 获取代理:
/**
 * 测试Demo
 *
 * @author azhuzhu 2020/7/11 14:20.
 */
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DemoServiceImpl implements IDemoService {
    private final DemoRepository demoRepository;
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertDemo(Demo demo) {
        demoRepository.insert(demo);
        throw new RuntimeException();
    }
    @Override
    public void doSomething() {
        this.self().insertDemo(new Demo());
    }
}










