Spring框架AOP底层实现原理 动态代理(JDK和cglib)

1.代理设计模式

  1. 相关对象

           目标对象  (老总 马云)

           代理对象  (秘书)

           抽象对象  (功能对象 吃饭,谈了小目标)

  1. 代理设计模式优势
  1. 保护目标对象
  2. 让目标对象功能更明确
  3. 扩展

2. 静态代理

1.编写功能接口

   public interface GongNeng {

    void chifan();

    void xiaomubiao();

}

2.编写目标对象类实现功能接口

public class LaoZong implements GongNeng{

    @Override

    public void chifan() {

        System.out.println("吃饭...");

    }

    @Override

    public void xiaomubiao() {

        System.out.println("深入谈一个亿的小目标...");

    }

}

3.编写代理对象类实现功能接口

public class MiShu implements GongNeng{

    LaoZong yunyun=new LaoZong();

   

    @Override

    public void chifan() {

        System.out.println("预约....");

        //调用目标对象的吃饭的行为

        yunyun.chifan();

        System.out.println("老总的联系方式:13838389438...");

    }

    @Override

    public void xiaomubiao() {

        System.out.println("预约....");

        //调用目标对象的小目标的行为

        yunyun.xiaomubiao();

        System.out.println("老总的联系方式:13838389438...");

    }

}

  1. 编写测试类

@Test

    public void test() {

        MiShu xm=new MiShu();

        //马总约饭

        xm.chifan();

        System.out.println("-------");

        xm.xiaomubiao();

    }

缺点:针对每一个功能方法都必须在代理类中提供一个对应的代理方法。

  1. 动态代理

       Jdk动态代理

           特点:1.jdk提供,不需要导入jar

                   2.目标对象必须实现接口,生成代理对象与目标对象实现同一接口。

       Cglib动态代理

           特点:  1.需要导入cglibjar

  1. 目标对象不需要实现接口,生成代理对象是目标对象子类。
  2.  Cglib效率更高

4.jdk动态代理

   1. 编写jdk动态代理控制器类,自动生成代理对象,并调用代理方法invoke

  

public class JdkProxyHandler implements InvocationHandler{

    LaoZong yunyun=new LaoZong();

    @Override

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("预约....");

        //调用目标对象的方法

        Object obj=method.invoke(yunyun, args);

        System.out.println("联系方式.....");

        return obj;

    }

}

  1. 测试类

@Test

    public void test() {

        //创建代理对象,通过jdk动态代理生成代理对象

        /*

         * 1.ClassLoader 类加载器

         * 2.Class[] interfaces  代理对象实现接口

         * 3.InvocationHandler   jdk代理控制器

         */

        GongNeng xm=(GongNeng) Proxy.newProxyInstance(JdkProxyTest.class.getClassLoader(),

                                           new Class[]{GongNeng.class},

                                            new JdkProxyHandler());

        System.out.println(xm);

        xm.chifan();

        System.out.println("-------------");

        xm.xiaomubiao();

    }

5.cglib动态代理

5.1 导入cglibjar

5.2  cglib动态代理控制器类,生成代理对象是目标对象的子类,并执行intercept

public class CglibProxyHandler implements MethodInterceptor{

    @Override

    public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {

        System.out.println("预约....");

        //调用目标对象的方法 --->arg3:代理对象(子类)的方法--->目标对象(父类)的方法

        Object obj=arg3.invokeSuper(arg0,arg2);

        System.out.println("联系方式.....");

        return obj;

    }

}

5.3 测试类

@Test

    public void test() {

        //创建代理对象,是目标对象的子类

        Enhancer e=new Enhancer();

        //1.指定父类:目标对象

        e.setSuperclass(LaoZong.class);

        //2.指定callback,指定代理对象调用一个对象的代理方法

        e.setCallback(new CglibProxyHandler());

        LaoZong xm=(LaoZong) e.create();

        xm.chifan();

        xm.xiaomubiao();

    }

   总结:目标对象只负责重点业务功能实现,其他辅助功能交给代理完成。

         可以在业务功能的前后进行额外功能的扩展。

6. 动态代理的典型应用场景

1.  事务控制

2.  日志记录

3.  权限或安全性验证

 

你可能感兴趣的:(spring,eclipse,spring,jar)