Cglig代理设计模式

/*测试类*/

package cglibProxy;

import org.junit.Test;

public class TestCglib {

  @Test
  public void test1(){
    CglibProxy cglibProxy=new CglibProxy();
    UserServiceImpl userServiceImpl = (UserServiceImpl)cglibProxy.createProxyInstance(new UserServiceImpl());
    userServiceImpl.addUser();
  }
}

/*代理类*/

package cglibProxy;

import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{

    //1.声明一个全局变量,被代理对象
    private Object target;

    //2.创建代理对象
    //参数是被代理对象
    public Object createProxyInstance(Object target){
    //赋值被代理对象
    this.target=target;
    Enhancer enhancer = new Enhancer();
    //设置代理对象的父类
    enhancer.setSuperclass(target.getClass());

    //设置回调函数
    //Callback是MethodInterceptor的父接口
    enhancer.setCallback(this);
    //返回创建出来的代理对象
    return enhancer.create();

  }

    //加工
    public Object intercept(Object proxy, Method method, Object[] arg,
      MethodProxy proxyMethod) throws Throwable {
      // TODO Auto-generated method stub

      //加工
      security();

    return proxyMethod.invoke(target, arg);

    }

    public void security(){
      System.out.println("进行权限控制");

    }
 }

/*需要被代理对象*/

package cglibProxy;

public class UserServiceImpl{

  public void addUser() {

    System.out.println("增加了用户");
    // TODO Auto-generated method stub

  }

  public void deleteUser() {

    System.out.println("删除了用户");
    // TODO Auto-generated method stub

  }

  public void alterUser() {

    System.out.println("修改了用户");
    // TODO Auto-generated method stub

  }

  public void findUser() {
    System.out.println("查询了用户");
    // TODO Auto-generated method stub

  }

  public void security(){
    System.out.println("进行了权限控制111");

  }

}

JDK动态代理设计模式

/*接口*/

package jdkProxy;

public interface IUserService {
  public void addUser();
  public void deleteUser();
  public void alterUser();
  public void findUser();
}

/*代理类*/

package jdkProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//整个类是切面类
public class JdkProxy implements InvocationHandler {

  //创建全局变量,被代理对象
  private Object target;

  //创建代理对象
  public Object createProxyInstance(Object target){
    //获取目标对象并赋值
    this.target=target;

    //根据目标对象创建对应的代理对象
    //三个参数,1.被代理对象的类加载器,2,被代理对象的所有接口,3,类型为InvocationHandler的对象,在本类中只有JdkProxy了
    //想要拿到类加载器首先拿到字节码,第三个参数this是指JdkProxy
    return Proxy.newProxyInstance(target.getClass().getClassLoader(),
    target.getClass().getInterfaces(), this);
  }

  //invoke这个方法是InvocationHandler的方法,实现需要重写
  //加工被代理对象
  //1.第一个参数是 刚创建的代理对象
  //2.第二个参数是需要被加工的方法,真实方法
  //3.第三个参数,需要被加工的方法的参数

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

    //加工
    security();

    //执行被代理对象的方法,最终是由被代理对象的方法
    return method.invoke(target, args);
  }

  //通知(增强)方法
  public void security(){
    System.out.println("进行权限控制");

  }

}

/*测试类*/

package jdkProxy;

import org.junit.Test;

public class TestJdkProxy {

  @Test
  public void tes1(){
    // IUserService userService=new UserServiceImpl();
    // userService.addUser();

    //创建代理对象,jdkProxy
    JdkProxy proxy=new JdkProxy();
    //执行创建代理对象的方法
    //参数就是被代理的对象
    //被代理对象要和代理对象接口要一致,要求被代理对象一定要实现接口

    //织入, weaver,就是创建一个代理对象,并调用被代理方法
   IUserService userService =(IUserService) proxy.createProxyInstance(new UserServiceImpl());
    userService.addUser();
  }
}

/*被代理对象*/

package jdkProxy;

public class UserServiceImpl implements IUserService {

  public void addUser() {

    System.out.println("增加了用户");
    // TODO Auto-generated method stub

  }

  public void deleteUser() {

    System.out.println("删除了用户");
    // TODO Auto-generated method stub

  }

  public void alterUser() {

    System.out.println("修改了用户");
    // TODO Auto-generated method stub

  }

  public void findUser() {
    System.out.println("查询了用户");
    // TODO Auto-generated method stub

  }

  public void security(){
    System.out.println("权限控制");

  }

}

动态代理:JDK动态代理和CGLIB代理的区别

代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法、实际执行的是被代理类的方法。

而AOP,是通过动态代理实现的。

一、简单来说:

  JDK动态代理只能对实现了接口的类生成代理,而不能针对类

  CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)

二、Spring在选择用JDK还是CGLiB的依据:

(1)当Bean实现接口时,Spring就会用JDK的动态代理

(2)当Bean没有实现接口时,Spring使用CGlib是实现

   (3)可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)

三、CGlib比JDK快?

  (1)使用CGLib实现动态代理,CGLib底层采用ASM字节码生成框架,使用字节码技术生成代理类,比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的方法进行代理,因为CGLib原理是动态生成被代理类的子类。

  (2)在对JDK动态代理与CGlib动态代理的代码实验中看,1W次执行下,JDK7及8的动态代理性能比CGlib要好20%左右。

设计模式---JDK动态代理和CGLIB代理的更多相关文章

  1. JDK动态代理和 CGLIB 代理

    JDK动态代理和 CGLIB 代理 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期期间创建一个接口的实现类来完成对目标对象的代理. 代码示例 接口 public interface ...

  2. JDK动态代理和CGLIB代理的区别

    一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件 ...

  3. 基于Spring AOP的JDK动态代理和CGLIB代理

    一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的 ...

  4. 动态代理:JDK动态代理和CGLIB代理的区别

    代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法.实际执行的是被代理类的方法. 而AOP,是通过动态代理实现的. 一.简单来说: JD ...

  5. JDK动态代理和cglib代理详解

    JDK动态代理 先做一下简单的描述,通过代理之后返回的对象已并非原类所new出来的对象,而是代理对象.JDK的动态代理是基于接口的,也就是说,被代理类必须实现一个或多个接口.主要原因是JDK的代理原理 ...

  6. JDK动态代理和cglib代理

    写一个简单的测试用例,Pig实现了Shout接口 public class MyInvocation implements InvocationHandler { Object k; public M ...

  7. 静态代理、动态代理和cglib代理

    转:https://www.cnblogs.com/cenyu/p/6289209.html 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处 ...

  8. SpringAOP-JDK 动态代理和 CGLIB 代理

    在 Spring 中 AOP 代理使用 JDK 动态代理和 CGLIB 代理来实现,默认如果目标对象是接口,则使用 JDK 动态代理,否则使用 CGLIB 来生成代理类. 1.JDK 动态代理 那么接 ...

  9. JDK动态代理和CGLib动态代理简单演示

    JDK1.3之后,Java提供了动态代理的技术,允许开发者在运行期间创建接口的代理实例. 一.首先我们进行JDK动态代理的演示. 现在我们有一个简单的业务接口Saying,如下: package te ...

随机推荐

  1. 【STM32H7教程】第58章 STM32H7的硬件JPEG应用之图片解码显示

    完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第58章       STM32H7的硬件JPEG应用之图片解 ...

  2. VisualTreeHelper 向下提取 元素

    private ChildType FindVisualChild<ChildType>(DependencyObject obj) where ChildType : Dependenc ...

  3. C# 集合类型学习

    如果你掌握了一门语言的数据结构 ,那么你离掌握这门语言 也不远了 1.列表 对于list,值得一提的是 Capacity 属性,使用默认的构造函数 ,让我们用代码来说明 var intList = n ...

  4. WordPress搭建教程---购买域名+购买VPS主机+域名DNS解析+网站环境+上传网站程序

    WordPress搭建教程 购买域名---NameSilo 购买VPS主机---Vultr 域名DNS解析 网站环境 上传网站程序 参考文章: 1. WordPress搭建教程 https://zhu ...

  5. JavaSE复习~开发环境的搭建 与 HelloWorld

    JDK的下载 访问Oracle官网,下载jdk,目前来说用的最多的是 8 版本 https://www.oracle.com/technetwork/java/javase/downloads/ind ...

  6. windows下如何快速删除大文件

    rmdir  磁盘:\文件夹的名字  /s /q; eg:rmdir E:\vue_workspace\KB\day08    /s/q /S 表示除目录本身外,还将删除指定目录下的所有子目录和文件. ...

  7. LeetCode简单题(三)

    题目一: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润. 注意你不能在买入股票前卖出股 ...

  8. CSS三列自适应布局(两边宽度固定,中间自适应)

    https://blog.csdn.net/cinderella_hou/article/details/52156333 https://blog.csdn.net/wangchengiii/art ...

  9. PHP实现链式操作的三种方法详解

    这篇文章主要介绍了PHP实现链式操作的三种方法,结合实例形式分析了php链式操作的相关实现技巧与使用注意事项,需要的朋友可以参考下 本文实例讲述了PHP实现链式操作的三种方法.分享给大家供大家参考,具 ...

  10. linux 镜像备份工具rsnyc

    1.本地拷贝文件nohup rsync -avzh /data/wwwroot/xhprof/* /mnt/xhprof/ &2.更改文件夹名称mv /data/wwwroot/xhprof ...