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. Django ORM 常用的13个方法

    介绍一个可以以py脚本方式运行ORM操作的方法: 可在项目内新建个py文件,复制项目内manage.py文件中的以下代码: if __name__ == "__main__": o ...

  2. 【MySQL】数据类型之字符相关

    " 目录 字符类型 char类型 varchar类型 实测 总结 枚举类型与集合类型 字符类型 官网:https://dev.mysql.com/doc/refman/5.7/en/char ...

  3. python requests.request 和session.request区别究竟在哪里

    import requests hd={"X-auth":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzeXN0ZW0iLCJBUEkiOiIvdW ...

  4. 应用 AddressSanitizer 发现程序内存错误

    作为 C/ C++ 工程师,在开发过程中会遇到各类问题,最常见便是内存使用问题,比如,越界,泄漏.过去常用的工具是 Valgrind,但使用 Valgrind 最大问题是它会极大地降低程序运行的速度, ...

  5. Vue-阻止页面回退

    1.原生js方法 <script language="javascript"> //防止页面后退 使用在vue时 挂载到mounted中 history.pushSta ...

  6. 「CF859E」Desk Disorder

    传送门 Luogu 解题思路 一眼想到二分图:但是求不了最大匹配方案数 oho. 于是考虑这么建图: 直接将一个人可以去的两把椅子连边,然后原图中的2n个点就会形成许多联通块,这个可以分步计数. 又因 ...

  7. 深入细枝末节,Python的字体反爬虫到底怎么一回事

    内容选自 即将出版 的<Python3 反爬虫原理与绕过实战>,本次公开书稿范围为第 6 章——文本混淆反爬虫.本篇为第 6 章中的第 4 小节,其余小节将 逐步放送 . 字体反爬虫开篇概 ...

  8. flink整合kafka报错 WARN - Bootstrap broker ip:9092 disconnected

    WARN - The configuration 'zookeeper.connect' was supplied but isn't a known config.WARN - The config ...

  9. 配置 DNS

    配置 DNS 如何自定义配置容器的主机名和 DNS 呢?秘诀就是 Docker 利用虚拟文件来挂载容器的 3 个相关配置文件. 在容器中使用 mount 命令可以看到挂载信息: $ mount /de ...

  10. web打开本地文件并读取内容

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...