Spring引介增强IntroductionAdvisor使用

环境:Spring5.2.14

创新互联建站主营鄂州网站建设的网络公司,主营网站建设方案,成都app软件开发,鄂州h5微信小程序开发搭建,鄂州网站营销推广欢迎鄂州等地区企业咨询

在不修改业务代码的情况下如何让某个类具有某项功能呢,比如具有XXXDAO接口的能力?

1 IntroductionAdvisor介绍

IntroductionAdvisor与PointcutAdvisor区别

  1. IntroductionAdvisor只能应用于类级别
  2. IntroductionAdvisor只能应用于Introduction类型的通知,而PointcutAdvisor可以应用于所有类型的通知
  3. IntroductionAdvisor的Advice需要实现目标的接口,而pintcutAdvisor中的Advice没有改要求

2 IntroductionAdvisor使用流程

假定我们的业务类CustomDAO希望具有DesignDAO(接口)的能力

2.1 目标接口

 
 
 
  1. public interface DesignDAO { 
  2.      
  3.     public void design() ; 
  4.      

2.2 Introduction拦截器

 
 
 
  1. public class CustomIntroductionInterceptor implements IntroductionInterceptor, DesignDAO { 
  2.     // 判断当前的拦截器是否实现了目标接口(DesignDAO,我们需要某个类具有指定接口的功能) 
  3.     @Override 
  4.     public boolean implementsInterface(Class intf) { 
  5.         return intf.isAssignableFrom(this.getClass()) ; 
  6.     } 
  7.  
  8.     @Override 
  9.     public Object invoke(MethodInvocation invocation) throws Throwable { 
  10.         System.out.println("我是通知类:IntroductionInterceptor") ; 
  11.         // 判断当前执行的方法所属类是否实现了目标接口 
  12.         // 这里必须要进行相应的判断拦截,否则会在没有被拦截的类方法执行的时候报错我 
  13.         // 因为你的其它类所对应的接口并没有在该拦截器中被实现。 
  14.         if (implementsInterface(invocation.getMethod().getDeclaringClass())) { 
  15.             return invocation.getMethod().invoke(this, invocation.getArguments()) ; 
  16.         } 
  17.         return invocation.proceed() ; 
  18.     } 
  19.  
  20.     @Override 
  21.     public void design() { 
  22.         System.out.println("接口实现了") ; 
  23.     } 
  24.          

2.3 IntroductionAdvisor定义

 
 
 
  1. @Component 
  2. public class CustomIntroductionAdvisor implements IntroductionAdvisor { 
  3.      
  4.     // 定义Advice通知 
  5.     @Override 
  6.     public Advice getAdvice() { 
  7.         return new CustomIntroductionInterceptor() ; 
  8.     } 
  9.  
  10.     // 该方法没有被使用,建议直接返回true 
  11.     @Override 
  12.     public boolean isPerInstance() { 
  13.         return true ; 
  14.     } 
  15.  
  16.     // 定义了所要实现的所有接口 
  17.     @Override 
  18.     public Class[] getInterfaces() { 
  19.         return new Class[] {DesignDAO.class} ; 
  20.     } 
  21.  
  22.     // 过滤类,返回true就会被匹配 
  23.     @Override 
  24.     public ClassFilter getClassFilter() { 
  25.         return new ClassFilter() { 
  26.             @Override 
  27.             public boolean matches(Class clazz) { 
  28.                 return CustomDAO.class.isAssignableFrom(clazz) ; 
  29.             } 
  30.         } ; 
  31.     } 
  32.  
  33.     // 在这里我们可以校验我们的Advice类是否实现了执行的接口getInterfaces中定义的接口 
  34.     @Override 
  35.     public void validateInterfaces() throws IllegalArgumentException { 
  36.         // 这里可以参考DefaultIntroductionAdvisor的实现 
  37.     } 
  38.  

这里可以查看示例文档37示例源码是如何执行的

2.4 验证

 
 
 
  1. @Component 
  2. public class CustomerDAOImpl implements CustomDAO { 
  3.          
  4.     public void update() { 
  5.         System.out.println("更新数据..." + this.getClass()) ; 
  6.     } 
  7.  
  8.     public void save() { 
  9.         System.out.println("保存方法..." + this.getClass()) ; 
  10.     } 
  11.      

 业务类并没有实现DesignDAO接口。接下来看看通过上面定义IntroductionAdvisor是否可以让我们的业务类具有目标类的功能

 
 
 
  1. public class LauncherMain { 
  2.      
  3.     public static void main(String[] args) { 
  4.         System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true") ; 
  5.         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("com.pack") ; 
  6.         CustomDAO dao = ctx.getBean(CustomDAO.class) ; 
  7.         System.out.println(dao.getClass()) ; 
  8.         System.out.println(Arrays.toString(dao.getClass().getInterfaces())) ; 
  9.         dao.save() ; 
  10.         dao.update() ; 
  11.         if (DesignDAO.class.isAssignableFrom(dao.getClass())) { 
  12.             DesignDAO ddao = (DesignDAO) dao ; 
  13.             System.out.println("IntroductionAdvisor start...") ; 
  14.             ddao.design() ; 
  15.             System.out.println("IntroductionAdvisor end...") ; 
  16.         } 
  17.         ctx.close() ; 
  18.     } 
  19.      

 执行结果:

 
 
 
  1. class com.sun.proxy.$Proxy14 
  2. [interface com.pack.dao.CustomDAO, interface com.pack.interfaces.DesignDAO, interface org.springframework.aop.SpringProxy, interface org.springframework.aop.framework.Advised, interface org.springframework.core.DecoratingProxy] 
  3. 我是通知类:IntroductionInterceptor, interface com.pack.dao.CustomDAO 
  4. intf: interface com.pack.dao.CustomDAO 
  5. 我被调用了... 
  6. 保存方法...class com.pack.dao.CustomerDAOImpl 
  7. 我是通知类:IntroductionInterceptor, interface com.pack.dao.CustomDAO 
  8. intf: interface com.pack.dao.CustomDAO 
  9. 更新数据...class com.pack.dao.CustomerDAOImpl 
  10. IntroductionAdvisor start... 
  11. 我是通知类:IntroductionInterceptor, interface com.pack.interfaces.DesignDAO 
  12. intf: interface com.pack.interfaces.DesignDAO 
  13. 接口实现了 
  14. IntroductionAdvisor end... 

标题名称:Spring引介增强IntroductionAdvisor使用
文章出自:http://www.hantingmc.com/qtweb/news10/248060.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联