一般我们使用Aop对象时,常用动态代理模式,即是采用映射一个相同的类在此基础上进行前置后置操作。

动态代理多是采用原类实现父类接口,然后动态代理一个和原类相同的双胞胎兄弟类来实现映射。

父类

public interface InterF {
public void save();
}

需要映射的类

public class Origin implements InterF{
@Override
public void save() {
System.out.println("测试一下");
}
}

动态代理映射,此类需要传入相应的原类对象

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author bai
* @create 2019-10-25-16:47
*/
public class ProxyJdk implements InvocationHandler { private Object target; public Object getProxy(Object target){
this.target=target;
return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("我来了");
Object invoke = method.invoke(target, args);
System.out.println("我走了");
return invoke;
}
}

测试类

public class Mytest {

    public static void main(String[] args) {
Origin o=new Origin();
ProxyJdk pj=new ProxyJdk();
InterF proxy = (InterF) pj.getProxy(o); proxy.save();
}
}

cglib模式的代理和动态代理大同小异,模式上相同,但cglib采用的是直接实现父子类,继承原类来实现映射。

原类

public class Origin{
public void save() {
System.out.println("测试一下");
}
}

cglib映射类,此类也需要传入原类

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /**
* @author bai
* @create 2019-10-25-17:26
*/
public class CglibProxy implements MethodInterceptor{
private Object target;//被代理目标 public Object getProxy(Object target){
this.target=target;
Enhancer enhancer = new Enhancer();
//1.设置基类
enhancer.setSuperclass(target.getClass());
//2.设置回调接口
enhancer.setCallback(this);//MethodInterceptor实现类
//3.创建动态代理
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("准备前");
Object invoke = method.invoke(target, objects);
System.out.println("准备后");
return invoke;
}
}

o是传入的对象,method是相应的切点所切方法,objects即参数。

测试类

public class Mytest2 {
public static void main(String[] args) {
Origin o=new Origin();
CglibProxy cp=new CglibProxy();
Origin proxy = (Origin) cp.getProxy(o);
proxy.save();
}
}

cglib相对于动态代理少了一个父类,更加便捷。且cglib使用时需要导入相应的jar包

Aop动态代理和cglib的更多相关文章

  1. Spring中AOP的两种代理方式(Java动态代理和CGLIB代理)

    第一种代理即Java的动态代理方式上一篇已经分析,在这里不再介绍,现在我们先来了解下GCLIB代理是什么?它又是怎样实现的?和Java动态代理有什么区别? cglib(Code Generation ...

  2. Spring中AOP的两种代理方式(Java动态代理和CGLIB代理-转载

    内容是摘抄的,不知最初的原作者,见谅 Java 动态代理.具体有如下四步骤: 通过实现 InvocationHandler 接口创建自己的调用处理器: 通过为 Proxy 类指定 ClassLoade ...

  3. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

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

    Aspect默认情况下不用实现接口,但对于目标对象,在默认情况下必须实现接口 如果没有实现接口必须引入CGLIB库 我们可以通过Advice中添加一个JoinPoint参数,这个值会由spring自动 ...

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

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

  6. 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别。

    基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别. 我还是喜欢基于Schema风格的Spring事务管理,但也有很多人在用基于@Tras ...

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

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

  8. Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。

    借鉴:http://jinnianshilongnian.iteye.com/blog/1508018 基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional ...

  9. Java三种代理模式:静态代理、动态代理和cglib代理

    一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...

随机推荐

  1. PAT 甲级 1056 Mice and Rice (25 分) (队列,读不懂题,读懂了一遍过)

    1056 Mice and Rice (25 分)   Mice and Rice is the name of a programming contest in which each program ...

  2. mybatis/tk mybatis下实体字段是关键字/保留字,执行报错

    实体如下: import com.fasterxml.jackson.annotation.JsonFormat; import com.xxx.web.bean.PagesStatic; impor ...

  3. spark在windows的配置

    在spark-env.cmd添加一行 FOR /F %%i IN ('hadoop classpath') DO @set SPARK_DIST_CLASSPATH=%%i 修改:log4j.prop ...

  4. Spring Boot中在程序中获得application.properties中的值

    方法是使用@Value注解的方式注解一个值. 首先,在我们的application.properties中添加一个值如下: zifeiy.tmpfile.location=D:/duty 然后在我们的 ...

  5. oracle jdk和openjdk区别;idea如何加载jdk源码并调试jdk代码

    两个jdk的区别 oracle jdk是sun/oracle(甲骨文)公司的,部分jdk开源:相对比较稳定,使用的比较多. openjdk是完全开源的,据说是官方oracle唯一承认的开源版本. id ...

  6. Git操作记录、腾讯工蜂

    腾讯工蜂: http://git.code.tencent.com 登录-->>创建项目-->>获取仓库路径 https://git.code.tencent.com/dang ...

  7. Flutter 流式布局列表实例+上拉加载

    页面变化的几种方式: 一.StatefulWidget的setState形式 先声明两个变量. ; List<Map> list = []; 写了一个方法,获取数据: void _getH ...

  8. laravel 小知识点

    分块导出brokerageCharge = DB::table('表名')$brokerageCharge = $brokerageCharge->chunk(100,function($bro ...

  9. php 将图片文件转成base64编码的方法

    php 将图片文件转成base64编码的方法<pre><?php /** 文件转base64输出 * @param String $file 文件路径 * @return Strin ...

  10. python3.7 完美安装

    在安装python3.7的过程中,我发现如果不加注意,pip3是无法被安装的.而这就不能算是完整安装python3了. 所以,我总结一下,如何完美安装python3.7.   依赖 yum insta ...