【Policy】使用 InitializingBean 实现策略时如何避免AOP失效

使用InitializingBean实现策略模式

  • 参考策略模式示例中的第一种实现方式.
  • 代码demo项目

不同的注入方式对AOP注解的影响

部分策略代码及测试代码

public interface TraditionOrderService extends InitializingBean {
  // ...
}
@Service
public class TraditionOrderServiceImpl implements TraditionOrderService {
  // afterPropertiesSet 注入方法见后续
}
  • 测试类
@Autowired
private TraditionOrderService traditionOrderService;

InitializingBean invoicePolicyService = InvoicePolicyFactory.getByType(1);

1.使用this注入会导致所有的AOP注解失效

@Override
public void afterPropertiesSet() {
  InvoicePolicyFactory.register(1, this);
}
  1. 实现类无AOP注解的注入结果(推荐)
    无AOP注解的注入结果
  2. 实现类有AOP注解的注入结果
    有AOP注解的注入结果
  • 这种方式给策略工厂注入的对象一定是非反向代理的对象,所以AOP注解都失效.

@Async @Transactional @GdLock @Monitor等注解都会失效

2.使用applicationContext.getBean()注入仅@Async失效

@Autowired
private ApplicationContext applicationContext;
@Override
public void afterPropertiesSet() {
  InvoicePolicyFactory.register(1, applicationContext.getBean(TraditionOrderService.class));
}
  1. 实现类无AOP注解的注入结果
    实现类无AOP注解的注入结果
  2. 实现类只有@Async注解的注入结果
    只有@Async注解的注入结果
  3. 实现类有@Async和其他AOP注解的注入结果
    有@Async和其他AOP注解的注入结果
  4. 实现类无@Async注解的注入结果(推荐)
    实现类无@Async注解的注入结果
  • 没有AOP注解或仅有@Async时,这种方式给策略工厂注入的对象是非反向代理的对象; 否则,注入CGLIB反向代理的对象.所以,@Async外的AOP注解有效.

可以简单的认为@Async注解会失效,其他AOP注解有效.

3.使用@Autowired注入可能仅@Async有效

@Lazy
@Autowired
private TraditionOrderService service;
@Override
public void afterPropertiesSet() {
  InvoicePolicyFactory.register(1, service);
}
  • 这种方式给策略工厂注入的对象一定是JDK反向代理的对象.

可以简单的认为@Async注解有效,其他AOP注解失效.

  1. 实现类无AOP注解的注入结果
    无AOP注解的注入结果
  2. 实现类只有@Async注解的注入结果(推荐)
    只有@Async注解的注入结果
  3. 实现类无异步或混合的注入结果
    无异步或混合的注入结果

总结

没有AOP注解(不需要反向代理)使用任意一种
没有@Async使用第二种
仅有@Async使用第三种

强烈建议把@Async和其他AOP注解进行物理隔离,分别放在不同的实现类中

你可能感兴趣的:(AOP,策略模式,spring,boot,策略模式,AOP失效)