动态代理

java的反射机制

java是静态类型的语言,语言的编译信息是在编译的时候检查的,本来是不能在运行时检查的,而有了反射机制,就可以在运行时检查语言的类型信息,还可以直接操作类或者操作对象,比如可以获取一个对象的类定义,可以获取一个类所声明的类和方法,调用方法。

反射机制使java可以在运行时操作元数据或者对象,这样即可以在运行时获取信息在进行处理,代码更灵活。

反射提供的AccessibleObject.setAccessible(boolean flag)。它的子类也都大都重写了这个方法,我们可以再运行时修改成员的访问限制!

setAccessible的应用场景很广泛,例如平常的开发、测试、依赖注入还有各种框架中,在O/R Mapping框架中,我们为一个java实体对象,运行时生成getter、setter,这对于加载数据和持久化数据很有必要,框架通常利用反射来完成自动生成getter。setter的逻辑,不需要我们手动写这些重复代码。

另一个典型场景就是绕过API的访问控制

动态代理

使用动态代理可以方便动态地构建代理,动态地调用代理方法,在很多场景中国都有应用,例如PPC调用,面向切面编程AOP。

实现动态代理有很多方法,比如JDK自身提供的动态代理使用反射机制实现的。还有其他的实现方式,例如ASM,cglib(基于ASM)等。

动态代理要解决什么问题?

可以让调用者和实现者之间解耦,解决了两者的耦合问题。比如进行RPC调用,框架内部的寻找地址,序列化、反序列化等,这些信息对于调用者没有多少意义,通过代理把这些细节屏蔽掉,提供更友好的界面。

动态代理首先是一个代理机制,结合设计模式的代理模式就容易理解了,代理相当于对调用目标的一个包装,调用不是直接发生,二是通过代理完成的。很多动态代理的场景,可以看成是装饰器(Decorator)模式的应用。

下面看一个JDK动态代理的简单例子。

public class MyDynamicProxy {
	public static void main(String[] args) {
			HelloImpl hello = new HelloImpl();
			MyInvocationHandler handler = new MyInvocationHandler(hello);
			//构造代码实例
			Hello proxyHello = (Hello)Proxy.newProxyInstance(HelloImpl.class.getClassLoader(), 
								HelloImpl.class.getInterfaces(), handler);
			//调用代理方法
			proxyHello.sayHello();
	}
}
interface Hello {
	void sayHello();
}
class HelloImpl implements Hello {
	@Override
	public void sayHello() {
		System.out.println("hello world");
	}
}
class MyInvocationHandler implements InvocationHandler {
	private Object target;
	public MyInvocationHandler(Object target) {
		this.target = target;
	}
	@Override
	public Object invoke(Object proxy, Method method,  Object[] args) throws Throwable {
		System.out.println("Invoking sayHello");
		Object result = method.invoke(target, args);
		return result;
	}
}

上面的JDKproxy例子,实现了动态代理的构建和代理。首先,实现对应的InvocationHandler,然后通过Hello接口,给被调用对象生成代理对象,然后应用功能程序就可以通过代理对象来运行被调用目标。
这种实现方式以接口为中心,我们实例化的是代理对象,而不是真正的被调用类型。

如果被调用者没有实现接口,我们还想使用动态代理机制,就可以考虑cglib方式。SpringAOP支持两种动态代理模式,JDK动态代理和cglib。如果选择cglib模式就可以克服对接口的依赖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值