zoukankan      html  css  js  c++  java
  • SpringAOP之动态代理

    一、动态代理:

          1.在原有的静态代理的基础上进一步的完善,由于静态代理中,重复写了相同的代码使得代码的整体结构显得冗余,而且还不同的核心类还需要有不用的代理类,是写死了的具体的类。所以需要使用动态代理来代替静态代理。

          2.具体实例:

            ⑴、业务介绍:

              假定高三学生为核心类,学生的家人是代理类。高三学生需要做的核心业务有:在家学习(studyAtHome)、在学校学习(studyAtHome);家人需要做的非核心业务为:准备饭菜(买、洗、炒、煮饭)。准备补品(购买、熬制、加佐料)。 

            ⑵、创建一个高三学生接口:G3Student

    package aop_002;
    
    //首先定义一个接口,用来高三学生来是实现,
    //在这个接口中声明一个在家学习和一个在学校学习的方法
    public interface G3Student {
    
        public void studyAtHome(String core);
        public void studyAtSchool(String core);
        
    }

              ⑶、创建一个高三学生(G3Student_boy),实现高三学生接口(G3Student),这个高三学生的类就是核心类。

    package aop_002;
    
    /*
     * 本例演示的是动态代理
    */
    
    //定义一个高三学生的类(目标对象、核心对象、target对象),实现了高三学生的接口。
    public class G3Student_boy implements G3Student {
    
        
        //高三学生 的第一个业务流程:在家学习
        public void studyAtHome(String core) {
            
            //核心的事情是在家学习。
            System.out.println(core+"在HOME学习");
            
        }
    
        //高三学生 的第二个业务流程:在学校学习
        public void studyAtSchool(String core) {
    //核心的事情是在家学习。
            System.out.println(core+"在SCHOOOL学习");
        
      } }

              ⑷、创建一个高三学生的代理类(G3Student_handler),并且实现了InvocationHandler接口

    package aop_002;

    import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class G3Student_handler implements InvocationHandler { private Object g3Stu; public G3Student_handler(Object g3Stu) { this.g3Stu = g3Stu; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //调用代理的在核心对象处理核心业务之前的方法 before(); //核心对象的核心方法 Object returnValue = method.invoke(g3Stu, args); //调用代理的在核心对象处理核心业务之后的方法 after(); return returnValue; } private void before(){ //这个是代理(G3Student_handler)准备饭菜的需要做的流程: System.out.println("代理:准备买菜"); System.out.println("代理:准备洗菜"); System.out.println("代理:准备炒菜"); System.out.println("代理:准备煮饭"); System.out.println("-----------------"); } private void after(){ //这个是代理(G3Student_handler)准备补品的需要做的流程: System.out.println("-----------------"); System.out.println("代理 :购买补品"); System.out.println("代理 :熬制部品"); System.out.println("代理 :加入佐料"); System.out.println(); } }

               ①、其中,和静态代理不同的是,动态代理的代理类中定义了一个以Object类型的属性,而静态代理定义的是具体的G3Student的接口类型的属性。所以,动态代理这样定义保证了,这个代理可以带不同的个核心类如:G3Student_boy、G3Student_girl。

               ②、这句代码意思:自动调用传入的核心类对象(G3Student_boy)的方法,并且传入参数args,返回一个Object类型的值。具体是调用什么方法,传入什么参数,都不需要我们具体关注,只需写上这条代码,并且把返回值返回即可

                

              ⑸、创建一个测试类Test:

    package aop_002;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Proxy;
    
    public class Test {
    
        public static void main(String[] args) {
            
            G3Student boy = new G3Student_boy();        
            
            InvocationHandler handler1 = new G3Student_handler(boy);
            
         G3Student g3boy
    = (G3Student)Proxy.newProxyInstance(boy.getClass().getClassLoader(), boy.getClass().getInterfaces(),handler1); g3boy.studyAtSchool("小明"); g3boy.studyAtHome("小明"); } }

                ①、首先,需要创建一个高三学生对象,其次需要创建一个代理类对象,最后使用Proxy创建一个高三学生对象,再调用方法即可。

              ②、可能有的人会问,为什么不直接使用第一次创建的高三学生对象直接调用方法呢?如果使用第一次创建的高三学生对象直接调用方法,那么就没有代理做的事情显示,所以应该时候用Proxy创建的高三学生对象,Proxy等于是高三学生对象和代理对象进行一次整合,使它们两个有机结合在一起,各自做各自的事情。

              测试结果:

                                


          谢谢浏览!

       

  • 相关阅读:
    JS 中 console 的用法
    C#可扩展编程之MEF学习笔记(二):MEF的导出(Export)和导入(Import)
    C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo
    MEF框架使用总结
    webfunny前端监控开源项目
    我从Vue源码中学到的一些JS编程技巧
    nodejs 发送邮件demo
    从零开始手写Promise
    概率论要点
    行列式技巧
  • 原文地址:https://www.cnblogs.com/demoMeng/p/5881473.html
Copyright © 2011-2022 走看看