当前位置: 首页 > 编程笔记 >

spring cglib 与 jdk 动态代理

封烈
2023-03-14
本文向大家介绍spring cglib 与 jdk 动态代理,包括了spring cglib 与 jdk 动态代理的使用技巧和注意事项,需要的朋友参考一下

1. 概述

JDK动态代理是利用java反射机制 生成一个实现接口的匿名类, 在调用具体方法前调用InvocationHandler来处理

Cglib动态代理是 利用asm开源包 把被代理类的class文件加载进来 通过修改其字节码生成子类来处理  

如果目标对象实现了接口 那么默认使用jdk代理(可以强制使用cglib代理)

如果没有实现接口 必须使用cglib代理

强制使用cglib代理需要

  *引入cglibjar包

  *配置spring <aop:aspectj-autoproxy proxy-target-class="true"/>    

cglib因为是动态生成被代理类的子类 并覆盖被代理类的方法 来实现的 所以 被代理方法不要使用final修饰   

2. 代码示例

2.1 cglib代理类

package com.rocky.spring;

import java.lang.reflect.Method;

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

public class CglibProxy {

  public static void main(String[] args) {
    final UserService service = new UserService();
    Enhancer hancer = new Enhancer();
    hancer.setSuperclass(service.getClass());
    hancer.setCallback(new MethodInterceptor(){

      @Override
      public Object intercept(Object proxy, Method method, Object[] arg2,
          MethodProxy arg3) throws Throwable {
        System.out.println("增强前 ... Cglib");
        Object invoke = method.invoke(service, arg2);
        System.out.println("增强后 ... Cglib");
        return invoke;
      }});
    UserService userService = (UserService) hancer.create();
    userService.sayHello();

  }
}
//需要引入cglib-2.2.jar 和org.objectweb.asm-3.3.1.jar 
//输出
//增强前 ... Cglib
//this userService works....
//增强后 ... Cglib

被代理类UserService

package com.rocky.spring;

public class UserService {

  public void sayHello(){
    System.out.println("this userService works....");
  }
}

2.2 jdk代理接口

package com.rocky.spring;

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

public class JdkProxy {

  public static void main(String[] args) {
    final ActorService service = new ActorServiceImpl();
    ActorService actorService = (ActorService) Proxy.newProxyInstance(
        service.getClass().getClassLoader(), service.getClass()
            .getInterfaces(), new InvocationHandler() {
          @Override
          public Object invoke(Object proxy, Method method,
              Object[] args) throws Throwable {
            System.out.println("增强前...jdk");
            Object invoke = method.invoke(service, args);
            System.out.println("增强后...jdk");
            return invoke;
          }
        });
    actorService.sayHi();
  }
}
//增强前...jdk
//Honestly, I do the work.
//增强后...jdk

被代理接口及实现类

package com.rocky.spring;
public interface ActorService {
  public void sayHi();
}
-----------------
package com.rocky.spring;
public class ActorServiceImpl implements ActorService {

  @Override
  public void sayHi() {
    doSomething();
  }

  private void doSomething() {
    System.out.println("Honestly, I do the work.");
  }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持小牛知识库!

 类似资料:
  • 本文向大家介绍详解Java JDK动态代理,包括了详解Java JDK动态代理的使用技巧和注意事项,需要的朋友参考一下   今天来看看Java的另一种代理方式——JDK动态代理   我们之前所介绍的代理方式叫静态代理,也就是静态的生成代理对象,而动态代理则是在运行时创建代理对象。动态代理有更强大的拦截请求功能,因为可以获得类的运行时信息,可以根据运行时信息来获得更为强大的执(骚)行(操)力(作)。

  • 本文向大家介绍浅谈Java代理(jdk静态代理、动态代理和cglib动态代理),包括了浅谈Java代理(jdk静态代理、动态代理和cglib动态代理)的使用技巧和注意事项,需要的朋友参考一下 一、代理是Java常用的设计模式,代理类通过调用被代理类的相关方法,并对相关方法进行增强。加入一些非业务性代码,比如事务、日志、报警发邮件等操作。 二、jdk静态代理 1、业务接口 2、业务实现类 3、代理类

  • 本文向大家介绍一个简单JDK版动态代理,包括了一个简单JDK版动态代理的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了手动实现的一个简单JDK版动态代理,供大家参考,具体内容如下 一.实现步骤 1.根据目标类的接口类型生成代理类的java文件。 2.编译代理类java文件为.class字节码文件。 3.将编译好的字节码文件加载到jvm中。 4.生成代理类对象并返回。 二.代码实现 1

  • 本文向大家介绍手动模拟JDK动态代理的方法,包括了手动模拟JDK动态代理的方法的使用技巧和注意事项,需要的朋友参考一下 为哪些方法代理? 实现自己动态代理,首先需要关注的点就是,代理对象需要为哪些方法代理? 原生JDK的动态代理的实现是往上抽象出一层接口,让目标对象和代理对象都实现这个接口,怎么把接口的信息告诉jdk原生的动态代理呢? 如下代码所示,Proxy.newProxyInstance()

  • 问题内容: JDK Proxy类仅在工厂方法newProxyInstance()中接受接口。 是否有可用的解决方法或替代实施?如果我必须将方法提取到接口以使其能够与代理一起使用,则用例是有限的。我想包装它们以在运行时应用基于注释的动作。 问题答案: 您可以像这样使用cglib: 例如,这使您可以使用默认的实现方法来构建抽象类。但是您可以将增强器更改为所需的增强器。

  • 问题内容: 如果是代理设计模式,那么JDK的动态代理和第三方动态代码生成API(例如CGLib)有什么区别? 使用这两种方法之间的区别是什么?何时应该优先选择另一种方法? 问题答案: JDK动态代理只能按接口进行代理(因此,您的目标类需要实现一个接口,然后该接口也可以由代理类实现)。 CGLIB(和javassist)可以通过子类化创建代理。在这种情况下,代理将成为目标类的子类。无需接口。 因此,