Java动态代理(jdk自带的与cglib的区别)

代理分为两种:静态代理、动态代理

静态代理:代理类是程序员创建或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在。设计模式中的代理模式使用的就是静态代理。

动态代理:有2种实现方式,一种是使用JDK的反射机制生成代理;另一种是cglib来生成代理。动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能。

设计模式中的代理模式

首先,介绍一下设计模式中的代理模式。

代理模式就是存在一个代理类,代理类和被代理类需要实现同一个接口,代理类调用被代理类对象中的相关方法,并且可以对产生的结果添加业务逻辑。使用代理可以在不改变目标对象方法的情况下对原方法的逻辑进行增强。

接口类


public interface IAnimal{
	
	public void sound();
}

被代理类

public class Cat implements IAnimal{

	@Override
	public void sound() {
		
		System.out.println("miao miao");
	}

}

代理类

public class CatProxy implements IAnimal{

	private IAnimal animal;
	
	public CatProxy(IAnimal animal) {
		this.animal=animal;
	}
	
	@Override
	public void sound() {
		System.out.println("CatProxy method sound begin");
		animal.sound();
		System.out.println("CatProxy method sound end");
	}

}

测试类

public class Test {

	public static void main(String[] args) {
		
		IAnimal animal=new Cat();//接口的引用指向实现类的对象
		CatProxy catProxy=new CatProxy(animal);
		catProxy.sound();//通过代理类调用委托类的sound方法
		
	}
}

输出:

静态代理有一个最大的缺陷:接口与代理类是1对1的,如果有多个接口需要代理,那就需要新建多个代理类。

JDK的反射机制生成代理

只能对接口进行代理,不能对普通的类进行代理,使用Java原生的反射API

需要提供一个接口,通过创建代理类,实现调用方与具体实现的解耦。

实现InvocationHandler接口中代理类

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

public class AnimalInvocationHandler implements InvocationHandler{

	private Object object;
	public AnimalInvocationHandler(Object object) {
		this.object=object;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		
		System.out.println("AnimalInvocationHandler invoke begin");
		Object result=method.invoke(object, args);//调用object所指向的实现类实例对象的method方法,args为调用方法传递过来的实参
		System.out.println("AnimalInvocationHandler invoke end");
		return result;
	}
}

测试类

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

public class Test {

	public static void main(String[] args) {
		
//		IAnimal animal=new Cat();//接口的引用指向实现类的对象
//		CatProxy catProxy=new CatProxy(animal);
//		catProxy.sound();//通过代理类调用委托类的sound方法
		
		IAnimal animal=new Cat();//接口的引用指向实现类的对象
		InvocationHandler handler = new AnimalInvocationHandler(animal);
		IAnimal proxy = (IAnimal) Proxy.newProxyInstance(IAnimal.class.getClassLoader(), new Class[]{IAnimal.class}, handler);
		proxy.sound();		
	}
}

输出内容:

cglib实现动态代理

能够代理普通类,cglib使用asm框架直接对字节码进行操作。

引入cglib相关的jar包:cglib-2.2.jar

若是maven项目,可以添加如下dependency

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

被代理类,不再实现Animal接口

public class Cat{

	public void sound() {
		
		System.out.println("miao miao");
	}

}

代理类

import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CgLibProxy implements MethodInterceptor{

	@Override
	public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

		System.out.println("CgLibProxy method intercept begin");
		Object intercept = methodProxy.invokeSuper(object, args);
		System.out.println("CgLibProxy method intercept end");
		
		return intercept;
	}
	
}

测试类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import net.sf.cglib.proxy.Enhancer;

public class Test {

	public static void main(String[] args) {
		
//		IAnimal animal=new Cat();//接口的引用指向实现类的对象
//		CatProxy catProxy=new CatProxy(animal);
//		catProxy.sound();//通过代理类调用委托类的sound方法
		
//		IAnimal animal=new Cat();//接口的引用指向实现类的对象
//		InvocationHandler handler = new AnimalInvocationHandler(animal);
//		IAnimal proxy = (IAnimal) Proxy.newProxyInstance(IAnimal.class.getClassLoader(), new Class[]{IAnimal.class}, handler);
//		proxy.sound();
		
		CgLibProxy cgLibProxy=new CgLibProxy(); 
		Enhancer enhancer = new Enhancer();  
        enhancer.setSuperclass(Cat.class);
        enhancer.setCallback(cgLibProxy);
		
        Cat proxy = (Cat) enhancer.create();
        proxy.sound();
	}
}

右键run as--java application,控制台console中报如下错误:

添加jar包:asm-3.3.1.jar

执行成功,输出结果如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值