环境:Spring5.2.14是如何在不修改业务代码的情况下让某个类拥有某个功能,比如拥有XXXDAO接口的能力?1IntroductionAdvisor介绍IntroductionAdvisor和PointcutAdvisor的区别在类层面,IntroductionAdvisor只能应用于Introduction类型的通知,而PointcutAdvisor可以应用于所有类型的通知。IntroductionAdvisor的Advice需要实现目标接口,pintcutAdvisor中的Advice没有改动。需求2IntroductionAdvisor使用流程假设我们的业务类CustomDAO要CapableDesignDAO(interface)2.1目标接口publicinterfaceDesignDAO{publicvoiddesign();}2.2引入拦截器publicclassCustomIntroductionInterceptorimplementsIntroductionInterceptor,DesignDAO{//判断当前拦截器是否实现了目标接口(DesignDAO,我们需要某个类具有指定接口的功能)@OverridepublicbooleanimplementsInterface(Class>intf){returnintf.isAssignableFrom(this.getClass());}@OverridepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{System.out.println("Iamanotificationclass:IntroductionInterceptor");//判断当前执行的方法所属的类是否实现了目标接口//需要进行相应的判断和拦截,否则方法执行时会报错没有被拦截的类的被执行//因为inte你其他类对应的rface是不是在这个拦截器里实现的。if(implementsInterface(invocation.getMethod().getDeclaringClass())){returninvocation.getMethod().invoke(this,invocation.getArguments());}returninvocation.proceed();}@Overridepublicvoiddesign(){System.out.println("Interfaceimplemented");}}2.3IntroductionAdvisor定义@ComponentpublicclassCustomIntroductionAdvisorimplementsIntroductionAdvisor{//定义Advice通知@OverridepublicAdvicegetAdvice(){returnnewCustomIntroductionInterceptor();}/true/该方法没有使用,建议直接返回true@Overridepublicstbooleanis;}//定义所有要实现的接口@OverridepublicClass>[]getInterfaces(){returnnewClass>[]{DesignDAO.class};}//Filter类,返回true会匹配@OverridepublicClassFiltergetClassFilter(){returnnewClassFilter(){@Overridepublicbooleanmatches(Class>clazz){returnCustomDAO.class.isAssignableFrom(clazz);}};}//这里可以验证我们的Advice类是否实现了getInterfaces中定义的接口Interface@OverridepublicvoidvalidateInterfaces()throwsIllegalArgumentException{//这里可以参考DefaultIntroductionAdvisor的实现}}这里可以查看示例文档37如何执行th示例源代码2.4行验证@ComponentpublicclassCustomerDAOImplimplementsCustomDAO{publicvoidupdate(){System.out.println("更新数据..."+this.getClass());}publicvoidsave(){System.out.println("保存方法..."+this.getClass());}}业务类没有实现DesignDAO接口接下来看看上面IntroductionAdvisor的定义是否可以让我们的业务类具备目标类的功能真");AnnotationConfigApplicationContextctx=newAnnotationConfigApplicationContext("com.pack");CustomDAOdao=ctx.getBean(CustomDAO.class);System.out.println(dao.getClass());System.out.println(Arrays.toString(dao.getClass().getInterfaces()));dao.save();dao.update();if(DesignDAO.class.isAssignableFrom(dao.getClass())){DesignDAOddao=(DesignDAO)dao;System.out。println("IntroductionAdvisorstart...");ddao.design();System.out.println("IntroductionAdvisorend...");}ctx.close();}}执行结果:classcom.sun.proxy.$Proxy14[interfacecom.pack.dao.CustomDAO,interfacecom.pack.interfaces.DesignDAO,interfaceorg.springframework.aop.SpringProxy,interfaceorg.springframework.aop.framework.Advised,interfaceorg.springframework.core.DecoratingProxy]我是通知类:IntroductionInterceptor,interfacecom.pack.dao.CustomDAOintf:interfacecom.pack.dao.CustomDAO我是调用...保存方法...classcom.pack.dao.CustomerDAOImpl我是通知类:IntroductionInterceptor,interfacecom.pack.dao.CustomDAOintf:interfacecom.pack.dao.CustomDAO更新数据...classcom.pack.dao.CustomerDAOImplIntroductionAdvisorstart...我是通知类:IntroductionInterceptor,interfacecom.pack.interfaces.DesignDAOintf:interfacecom.pack.interfaces.DesignDAO接口实现IntroductionAdvisorend。..
