代理实现机制,Java中动态代理和cglib动态代理的实现机制

原创 2016年05月31日 15:34:46
代理是Java中一种常见的设计模式,代理不能够直接访问的类,通过代理类实现对内部
不能够直接访问的类的方法的调用,其特征是代理类与需要代理的类(委托类)具有相同
的功能,甚至是同一个接口的实现类。按照代理类存在的时期分为静态代理和动态代理两类。

静态代理:由程序创建生成源码,再对其进行编译,在程序运行前class文件已经存在。

动态代理:在程序运行的时候通过反射机制创建。

静态代理例子:

package core.java.proxy.stac;

public interface ProductService {
	
	public void detail(String productNo);

}

package core.java.proxy.stac;

public class ProductServiceImpl implements ProductService{

	@Override
	public void detail(String productNo) {
		System.out.println("这是编号为" + productNo + "的详细数据");
		
	}

}

package core.java.proxy.stac;

public class ProductProxy implements ProductService{
	
	private ProductServiceImpl productService;
	
	public ProductProxy(ProductServiceImpl productServiceImpl){
		this.productService = productServiceImpl;
	}

	@Override
	public void detail(String productNo) {
		System.out.println("product proxy before.............");
		productService.detail(productNo);
		System.out.println("product proxy after.............");
	}

}

package core.java.proxy.stac;

public class StacProxyTest {
	
	public static void main(String[] args) {
		ProductProxy proxy = new ProductProxy(new ProductServiceImpl());
		proxy.detail("30001245");
	}
}
输出结果:
product proxy before.............
这是编号为30001245的详细数据
product proxy after.............

由上面的例子可以看出静态代理类其实是对实现类的引用然后再对其方法进行调用,
并且静态代理类只能为一个类服务,如果有很多类需要代理就会创建很多代理类,
代码中出现大量的代理类。


为了解决静态代理带来的不便,Java中提供了动态代理的实现机制,如果想创建代理类
只需要实现InvocationHandler接口,实现其invoke方法即可。

Java动态代理实现例子:

package core.java.proxy;


/**
 * 实现的业务接口
 * @author admin
 *
 */
public interface UserService {
	
	public void sayHello(String name);

}

package core.java.proxy;


/**
 * 实际业务的实现类
 * @author admin
 *
 */
public class UserServiceImpl implements UserService{

	@Override
	public void sayHello(String name) {
		System.out.println("hello " + name + "!");
	}

}

package core.java.proxy;

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


/**
 * 业务代理类
 * @author admin
 *
 */
public class UserProxy implements InvocationHandler{
	
	/**
	 * 需要代理的原生对象
	 */
	private Object obj;
	
	public UserProxy(Object obj) {
		super();
		this.obj = obj;
	}

	/**
	 * @param proxy 被代理的对象
	 * @param method 需要调用的方法
	 * @param args  方法调用时需要的参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("proxy before..........");
		Object result = method.invoke(obj, args);
		System.out.println("proxy after............");
		return result;
	}
}

package core.java.proxy;

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


public class ProxyTest {
	
	public static void main(String[] args) {
		UserService userService = new UserServiceImpl();
		InvocationHandler invocationHandler = new UserProxy(userService);
		UserService proxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), invocationHandler);
		proxy.sayHello("zhangsan");
	}

}
输出结果:
proxy before..........
hello zhangsan!
proxy after............

动态代理可以实现所有需要代理的原生类的功能,解决了静态代理的缺陷。但是动态代理
也有自身的缺陷,就是动态代理只能代理有实现类的接口,这就需要代理的接口类必须有
实现类,这样程序中也会出现大量的实现类,为了解决这一缺陷,cglib就是对这一缺陷
的弥补。cglib的原理就是对目标类生成一个子类,覆盖其方法进行增强。因为采用的是
Java中继承的机制,因此不能对用了final修饰符的类进行代理。


cglib动态代理例子:

package core.java.proxy.cglib;

public interface TicketService {
	
	public void sell();

}

package core.java.proxy.cglib;

public class TicketBiz {
	
	public void sell(){
		System.out.println("卖出一张票");
	}

}

package core.java.proxy.cglib;

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 ProxyCglib implements MethodInterceptor{
	
	private Object target;
	
	public Object createProxy(Object target){
		this.target = target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());
		enhancer.setCallback(this);
		enhancer.setClassLoader(this.getClass().getClassLoader());
		return enhancer.create();
	}

	@Override
	public Object intercept(Object arg, Method method, Object[] objects,
			MethodProxy proxy) throws Throwable {
		System.out.println("sell ticket before..........");
		proxy.invokeSuper(arg, objects);
		System.out.println("sell ticket after..........");
		return null;
	}

}

package core.java.proxy.cglib;


public class CglibProxyTest {
	
	public static void main(String[] args) {
		ProxyCglib proxyCglib = new ProxyCglib();
		TicketBiz ticketBiz = (TicketBiz)proxyCglib.createProxy(new TicketBiz());
		ticketBiz.sell();
	}

}
输出结果:
sell ticket before..........
卖出一张票
sell ticket after..........


静态代理和动态代理比较:
静态代理预先生成好代理类通过编译生成class文件,程序运行时就能调用,
动态代理是程序运行时根据反射机制生成代理类,因此静态代理的速度要
比动态代理快一些。



版权声明:本文为博主原创文章,未经博主允许不得转载。

java 动态代理机制的理解和分析

引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执...
  • Leonardo9029
  • Leonardo9029
  • 2016年03月28日 10:22
  • 3526

细说java动态代理和cglib的动态代理

提到代理,想必大家对设计模式中的静态代理和动态代理都比较熟悉,小编之前在博客中对动态和静态代理进行了对比,这篇博文就只探讨java动态代理和cglib动态代理之间的区别; ♚  静态代理的温习    ...
  • YSC1123
  • YSC1123
  • 2016年06月18日 16:36
  • 1146

java代理(静态代理和jdk动态代理以及cglib代理)

说到代理,脑袋中浮现一大堆代理相关的名词,代理模式,静态代理,jdk代理,cglib代理等等。 记忆特别深刻的是,一次面试中,一位面试官问我,spring的AOP核心采用的设计模式是什么什么模式,阅读...
  • fighterandknight
  • fighterandknight
  • 2016年04月20日 17:34
  • 4531

系统架构设计——设计模式之代理模式(二)CGLIB动态代理实现

像上一篇所说的代理模式其实是静态代理,在实际开发中其实应用不大,因为他需要事先知道被代理对象是谁,而且被代理对象和代理对象实现了公共的接口。实际情况往往并不能满足这些条件,我们往往在写代理模式的时候并...
  • qq_25689397
  • qq_25689397
  • 2016年05月16日 18:38
  • 8283

动态代理proxy与CGLib的区别

昨天被人问及动态代理与CGlib的区别,赶紧回顾一下: 什么是代理?静态代理与动态代理静态代理实例JDK动态代理实例CGLib 简介CGLib 与JDK动态代理的区别     代理模式是Java...
  • hintcnuie
  • hintcnuie
  • 2013年09月03日 08:50
  • 23749

Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)

本文阐述:class 文件 和代码中的class 对象之间的关系;动态代理中Invocation Handler角色的由来;Javassist 和ASM框架生成字节码;类加载器...
  • u010349169
  • u010349169
  • 2014年06月03日 15:48
  • 44737

Spring—AOP两种代理机制对比(JDK和CGLib动态代理)

Sprign 动态代理机制 Spirng的AOP的动态代理实现机制有两种,分别是: 1)JDK动态代理: 具体实现原理: 1、通过实现InvocationHandlet接口创建自己的调...
  • qq1723205668
  • qq1723205668
  • 2017年02月22日 12:09
  • 2942

AOP的底层实现-CGLIB动态代理和JDK动态代理

详细介绍了AOP的核心功能(拦截功能)在底层是如何实现的;介绍了两种实现AOP的动态代理:jdk动态代理和cglib动态代理,并详细描述了它们在代码层面的实现。...
  • dreamrealised
  • dreamrealised
  • 2013年10月20日 19:53
  • 28879

Spring的两种代理方式:JDK动态代理和CGLIB动态代理

代理模式代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动。在一些情况下,一个客户不想或者不能够直接引用一个对象...
  • cckevincyh
  • cckevincyh
  • 2017年02月10日 14:04
  • 8863

JDK和Cglib实现动态代理实例及优缺点分析

Spring AOP使用的核心技术是动态代理,说到动态代理就不得不和设计模式中的代理模式联系起来,通过代理模式我们可以对目标类进行功能增强,在某个方法的执行前后增加一些操作,例如计算方法执行效率、打印...
  • Rongbo_J
  • Rongbo_J
  • 2015年10月17日 13:38
  • 3868
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:代理实现机制,Java中动态代理和cglib动态代理的实现机制
举报原因:
原因补充:

(最多只允许输入30个字)