文档章节

spring aop-代理篇,java Proxy代理&cglib代理

haoran_10
 haoran_10
发布于 2016/07/15 16:37
字数 1052
阅读 78
收藏 0

一、java原生代理

1、代理概念介绍

为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理 对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行 完请求后的后续处理。

2、代理分类

java代理分为两类,静态代理和动态代理。

静态代理通过代码的编写,生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成,所以不存在代理类的字节码文件。代理类和委托类的关系是在程序运行时确定。

3、动态代理示例

使用java.lang.reflect.Proxy进行创建

3.1 接口部分

使用Proxy创建代理,必须预先定义接口

package wang.conge.javasedemo.core.proxy; public interface HelloService { public String sayHello(String name); } 

3.2 业务实现部分

package wang.conge.javasedemo.core.proxy;

public class HelloServiceImpl implements HelloService {

    @Override
    public String sayHello(String name) {
        return "hello:" + name;
    }

}

3.3 代理业务部分

package wang.conge.javasedemo.core.proxy;

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

public class HelloInvocationHandler implements InvocationHandler{
    private Object delegate; 
    
    public HelloInvocationHandler(Object delegate){
        this.delegate = delegate;
    }
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("invoke");
        return method.invoke(this.delegate, args);
    }

}

3.4 测试代码

package wang.conge.javasedemo.core.proxy;

import java.lang.reflect.Proxy;

public class JavaProxyTest {
    public static void main(String[] args) {
        HelloInvocationHandler invocationHandler = new HelloInvocationHandler(new HelloServiceImpl());

        HelloService helloService = (HelloService) Proxy.newProxyInstance(HelloService.class.getClassLoader(),
                new Class[] { HelloService.class }, invocationHandler);

        System.out.println(helloService.sayHello("conge"));
    }
}

运行结果

invokehello:conge

3.5 Proxy代理总结

用法总结:

主要使用java.lang.reflect.Proxy 进行创建代理类
主要方法:public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h);

第一个参数是ClassLoader,也即是加载所要代理类的相应的ClassLoader
第二个参数是interfaces,即是所要代理类的接口
第三个参数是代理业务部分,需要实现InvocationHandler接口
                                          

优缺点总结:

优点:
1、可以替代java静态代理,集中式处理

缺点:
1、所代理的类,必须预先定义接口,不能直接没有定义接口的类
2、所代理的接口也必须是public类型,如果是package ,必须在访问包的顶层目录

二、Cglib代理

因为Proxy不能代理没有定义接口的类,缺陷比较大。但还有另外一个方案可以解决这个问题。cglib。

1.cglib介绍

cglib简述
           Cglib是一个优秀的动态代理框架,它的底层使用ASM在内存中动态的生成被代理类的子类,使用CGLIB即使代理类没有实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的Proxy动态代理:
使用CGLIB需要导入以下两个jar文件:
    $1:    asm.jar – CGLIB的底层实现
    $2:   cglib.jar – CGLIB的核心jar包。
CGLIB的核心类:
    net.sf.cglib.proxy.Enhancer – 主要的增强类
    net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现
    net.sf.cglib.proxy.MethodProxy – JDK的Java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用,如使用:
    Object o = methodProxy.invokeSuper(proxy, args);//虽然第一个参数是被代理对象,也不会出现死循环的问题。

2.使用cglib进行代理

2.1 所依赖cglib

<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.2</version></dependency>

2.2 业务服务

还是使用java原生代理的HelloServiceImpl , see 原生代理3.2

2.3 代理业务部分

package wang.conge.javasedemo.core.cglib;

import java.lang.reflect.Method;

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

public class HelloCglibHandler implements MethodInterceptor {
    private Object delegate; 
    
    public HelloCglibHandler(Object delegate){
        this.delegate = delegate;
    }
    
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("intercept");
        return method.invoke(delegate, args);
    }

}

2.4 测试代码

package wang.conge.javasedemo.core.cglib;

import net.sf.cglib.proxy.Enhancer;
import wang.conge.javasedemo.core.proxy.HelloServiceImpl;

public class EnhancerTest {
    public static void main(String[] args) {
        HelloCglibHandler cglibHandler = new HelloCglibHandler(new     HelloServiceImpl());

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(HelloServiceImpl.class);
        enhancer.setCallback(cglibHandler);
        
        HelloServiceImpl helloService = (HelloServiceImpl) enhancer.create();
        
        System.out.println(helloService.sayHello("conge"));
    }
}

运行结果:

intercepthello:conge

2.5 cglib代理总结

 

主要使用Enhancer进行创建代理类,可以直接对类进行代理,运行速度也比原生代理要快。

© 著作权归作者所有

共有 人打赏支持
haoran_10
粉丝 25
博文 88
码字总数 80846
作品 0
杭州
程序员
私信 提问
JDK动态代理与Cglib动态代理(转载)

spring容器通过动态代理再结合java反射思想可以使得方法调用更加简洁 一、动态代理概述: 与静态代理对照(关于静态代理的介绍 可以阅读上一篇:JAVA设计模式之 代理模式【Proxy Pattern】(...

思悟修
2015/08/14
0
0
Java设计模式综合运用(动态代理+Spring AOP)

AOP设计模式通常运用在日志,校验等业务场景,本文将简单介绍基于Spring的AOP代理模式的运用。 1. 代理模式 1.1 概念 代理(Proxy)是一种提供了对目标对象另外的访问方式,即通过代理对象访问...

landy8530
10/05
0
0
CGLIB子类代理和JDK动态代理示例和比较

Cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。 比较: JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现...

AI9o後
2017/11/06
0
0
Spring Proxy 动态代理(ProxyFactory)

一、动态代理生成技术栈分为两种: 1、JDK动态代理 JDK动态代理只能对实现了接口的类生成代理,而不能针对类 2、Cglib动态代理 CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其...

王微_1986
07/27
0
0
Spring的事务管理难点剖析(6):特殊方法成漏网之鱼

由于Spring事务管理是基于接口代理或动态字节码技术,通过AOP实施事务增强的。虽然Spring还支持AspectJ LTW在类加载期实施增强,但这种方法很少使用,所以我们不予关注。 对于基于接口动态代...

icheer
2012/07/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spark性能优化之道

Spark性能优化之道——解决Spark数据倾斜(Data Skew)的N种姿势 本文结合实例详细阐明了Spark数据倾斜的几种场景以及对应的解决方案,包括避免数据源倾斜,调整并行度,使用自定义Partition...

GordonNemo
18分钟前
2
0
大数据驱动业务决策,CDN实时日志重磅上线

摘要: 阿里云CDN上线了实时日志功能,打通日志服务(SLS)的能力,将CDN采集的实时日志,在小于60秒的时间内投递至日志服务,进行实时、交互式分析和报表呈现。通过CDN日志的实时分析,可以快...

阿里云官方博客
23分钟前
3
0
springCloud学习笔记系列(3)-服务容错保护:Spring Cloud Feign

Feign包含了Ribbon和Hystrix,这个在实战中才慢慢体会到它的意义,所谓的包含并不是Feign的jar包包含有Ribbon和Hystrix的jar包这种物理上的包含,而是Feign的功能包含了其他两者的功能这种逻...

快乐的小火柴
24分钟前
1
0
各种数据库数据类型差异

文本 整数 浮点数 decimal Hive数据库 create table default.foo ( a DECIMAL, -- Defaults to decimal(10,0) b DECIMAL(20), -- Defaults to decimal(20,0) c DECIMAL(9, 7), d DE......

了凡川
29分钟前
3
0
springboot中filter的用法

一、在spring的应用中我们存在两种过滤的用法,一种是拦截器、另外一种当然是过滤器。我们这里介绍过滤器在springboot的用法,在springmvc中的用法基本上一样,只是配置上面有点区别。 二、f...

xiaomin0322
47分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部