背景
SpringBoot项目,创建了一个serviceImpl共厂,为每个serviceImpl打了一个服务类型的注解,注解的内容匹配服务类型,实现自动选择服务调用的功能。
时序图
类图
问题
svcs是所有接口的实现类,通过获取注解的值判断需要调用哪个实现类。可是在加入@Transactional之后,发现FeedBackAnno注解消失了,无法获取值。
解决
因为@Transactional注解是通过动态代理的方式,导致生成的代理类没有继承serviceImpl中的注解,根本原因是注解没有设置继承属性,加上@Inherited属性即可。
@Rentention(RententionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface FeedBackSvcType {
public Enum type();
}
扩展
spring的动态代理实现有两种方式,一种是针对父类是一个接口的,通过实现jdk自带的InvocationHandler来创建一个和业务类平行的一个,且实现了同一个接口的代理类,通过在代理类中加入前置和后置来实现代理。第二种是针对没有父接口的,通过CGLib库加载实现类的字节码,动态生成一个实现类的子类,这个子类有前置和后置,通过调用super.logic来调用业务逻辑。
总结,一个是创建一个和实现类平级的类并包含一个实现类对象;一个是通过继承来创建的实现类的子类。