Java 动态代理实践AOP

大家都知道Spring中AOP是通过Java动态代理实现的,今天就来简单学习下demo。

Java动态代理主要有两个核心类,InvocationHandler和Proxy。

/**
 * {@code InvocationHandler} is the interface implemented by
 * the <i>invocation handler</i> of a proxy instance.
 *
 * <p>Each proxy instance has an associated invocation handler.
 * When a method is invoked on a proxy instance, the method
 * invocation is encoded and dispatched to the {@code invoke}
 * method of its invocation handler.
 *
 * @author      Peter Jones
 * @see         Proxy
 * @since       1.3
 */
public interface InvocationHandler

所有的Handler类要实现InvocationHandler接口,并关联到Proxy实例上,最后会分发到InvocationHandler的invoke方法上。

/**
 * {@code Proxy} provides static methods for creating dynamic proxy
 * classes and instances, and it is also the superclass of all
 * dynamic proxy classes created by those methods.
 *
 * <p>To create a proxy for some interface {@code Foo}:
 * <pre>
 *     InvocationHandler handler = new MyInvocationHandler(...);
 *     Class proxyClass = Proxy.getProxyClass(
 *         Foo.class.getClassLoader(), new Class[] { Foo.class });
 *     Foo f = (Foo) proxyClass.
 *         getConstructor(new Class[] { InvocationHandler.class }).
 *         newInstance(new Object[] { handler });
 * </pre>
 * or more simply:
 * <pre>
 *     Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
 *                                          new Class[] { Foo.class },
 *                                          handler);
 * </pre>
 *
 ****************************
 */
public class Proxy implements java.io.Serializable

通过该类的静态方法创建要动态代理的类。

下面看下demo

1. 先创建一个接口

public interface TargetInterface {
	int targetMethod(int num);
}

2. 实例化该接口

public class TargetClass implements TargetInterface {
	@Override
	public int targetMethod(int number) {
		System.out.println("调用目标类的方法targetMethod...");  
        return number;  
	}
}

3. 创建代理处理类,InvocationHandler子类

public class ProxyHandler implements InvocationHandler {
	Object concreteClass;
	public ProxyHandler(Object concreteClass) {
		this.concreteClass = concreteClass;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
        System.out.println("proxy:"+proxy.getClass().getName());  
        System.out.println("method:"+method.getName());  
        System.out.println("args:"+args[0].getClass().getName());  

        System.out.println("Before invoke method...");  
        Object object = method.invoke(concreteClass, args);
        System.out.println("After invoke method...");  
        return object;  
	}
}
proxy:  指代我们所代理的那个真实对象
method: 指代的是我们所要调用真实对象的某个方法的Method对象
args:  指代的是调用真实对象某个方法时接受的参数
public class Example {
	public static void main(String[] args) {
		TargetClass cc = new TargetClass();
		InvocationHandler ih = new ProxyHandler(cc);
		TargetInterface tf = (TargetInterface) Proxy.newProxyInstance(cc.getClass().getClassLoader(), cc.getClass().getInterfaces(), ih);
		
		int i = tf.targetMethod(5);
	}
}
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

loader:  一个ClassLoader对象,定义了由哪个ClassLoader对象来对生成的代理对象进行加载
interfaces:  一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
h:  一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上

注意:通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象,它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号

动态代理有个缺陷,就是创建时需要参数interfaces,即被代理的类,需要实现该接口。

转载于:https://my.oschina.net/android520/blog/700945

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值