设计模式---JDK动态代理和CGLIB代理

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%左右。

原文地址:https://www.cnblogs.com/binghuaZhang/p/11566063.html

时间: 2024-11-05 11:24:23

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

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

一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理. 1.如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 2.如果目标对象实现了接口,可以强制使用CGLIB实现AOP 3.如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换 如何强制使用

jdk动态代理和cglib代理总结

首先我们来谈谈jdk的动态代理,它允许开发者在运行期创建接口的代理实例,那么当我们在运行过程中调用某个实例的某个方法时,可以使用代理对象去具体实现它,从而达到aop的效果. (1)jdk的动态代理主要涉及两个类:proxy和invocacationHandler,invocationHandler里面包含了横切逻辑,并且可以使用反射调用目标类的方法(就是切点),proxy类主要是使用它的一个newinstance方法去创建一个代理实例. 下面我们来看代码: package com.yue.tes

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

一.AOP的概念  在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型.利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率. 二.主要用途 将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务

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

代理模式:代理类和被代理类实现共同的接口(或继承),代理类中存有指向被代理类的索引,实际执行时通过调用代理类的方法.实际执行的是被代理类的方法. 而AOP,是通过动态代理实现的. 一.简单来说: JDK动态代理只能对实现了接口的类生成代理,而不能针对类 CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承) 二.Spring在选择用JDK还是CGLiB的依据: (1)当Bean实现接口时,Spring就会用JDK的动态代理 (2)当Bean没有实现接口时,Spring使

JDK动态代理和cglib代理

写一个简单的测试用例,Pig实现了Shout接口 public class MyInvocation implements InvocationHandler { Object k; public MyInvocation(Object k) { this.k = k; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //System.out.print

JDK动态代理和CGLIB动态代理

转载自http://www.itzhai.com/java-dong-tai-dai-li-zhi-jdk-dong-tai-dai-li-he-cglib-dong-tai-dai-li-mian-xiang-qie-mian-bian-cheng-aop-yuan-li.html 静态代理 静态代理相对来说比较简单,无非就是聚合+多态: 参考:设计模式笔记 – Proxy 代理模式 (Design Pattern) 动态代理 我们知道,通过使用代理,可以在被代理的类的方法的前后添加一些处理方

关于JDK动态代理和CGLIB动态代理

1. 代理模式 一句话总结:为其他对象提供一种代理以控制对这个对象的访问.千篇一律的介绍:代理模式是常用的java设计模式,他的特征是代理类与委托类(或目标类)有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创建时期,代理类可以分为两种. 静态代理:由程序员创建或特定工具

【Spring】AOP之JDK动态代理和CGLib动态代理

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 一.JAVA动态代理  1.1 代理模式         代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务. 按照代理的创

JDK动态代理和CGLIB动态代理+源码下载

在上一篇文章-java代理详解讲解实现机制,一种是继承另外一种是组合,而且通过做实现也证明使用组合的方式更加的灵活.之后提到了代理的两种种类,一种是静态代理,另外一种是动态代理.上一篇文件中着重介绍的是静态代理(相对于动态代理很容易理解).这一片文章就接着介绍动态代理. 动态代理实现的最终效果:通过以一个统一的方式实现对任意的接口/类的代理.相比较静态代理而言,我们可以不用再无限制的增加代理类,不用再写许多重复的代码.很符合面向对象设计原则中的"开闭原则":对修改关闭,对扩展开放. 动