java动态代理示例,自己实现Aop

这次的博客将会介绍两种动态代理的方式,一种为jdk动态代理,一种为cglib动态代理,在代码方面将会使用最少的代码来完成,类会尽量的少,帮助大家理解。

先讲一下这两种代理方式的主要区别,jdk动态代理要求代理的类必须要有实现的接口,而cglib是通过创建子类进行代理,不需要实现接口,具体操作马上介绍。

首先创建一个接口、一个类实现接口:

public interface Action {
	void action();
}
public class Person implements Action{
	@Override
	public void action() {
		System.out.println("切面");
	}
}

下面创建一个处理器类,实现jdk的InvocationHandler接口,这个处理器类用来对代理对象进行处理:

public class PersonInvocationHandler implements InvocationHandler{
	private Person p;
	public PersonInvocationHandler (Person p){
		this.p = p;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("前置事件");
		method.invoke(p, args);
		System.out.println("后置事件");
		return null;
	}
}

 在这个类中的参数介绍:

private Person p:需要进行Aop的对象,你可以改为任何想要的形式,比如private Object obj;或者你自己现在

创建一个类,然后写入。

Object proxy:基本不会用到,是jdk动态代理生成的对象,之后马上介绍,可以忽略。

Method method:jdk动态代理生成的代理对象所调用的方法。

Object args[]:上面method的参数。

 

这样看起来,我们的对象和PersonInvocationHandler还完全没有联系起来,接下来,我们将两者进行关联,创建一个Test测试类,内部只有一个main方法:

public class Test {
	public static void main(String[] args) {
		Person p = new Person();
		InvocationHandler h = new PersonInvocationHandler(p);
		
		Action proxy = (Action) Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), h);
		proxy.action();
	}
}

 首先创建一个Person类的对象p,我们要对p的action方法进行Aop,那么便需要与之前的PersonInvocationHandler联系起来,我们在创建PersonInvocationHandler的时候指定了构造函数,那么按照构造函数创建一个对象h,此h对象便是处理器。

接着创建一个代理对象,该对象通过java.lang.reflect.Proxy类的newProxyInstance方法创建,参数三个,分别为:

ClassLoader:类加载器,使用p.getClass().getClassLoader()即可。

Class<?>[]:jdk创建的代理对象需要实现的接口,数组形式。

InvocationHandler:处理器,创建的代理对象的任何方法都会经过该处理器,aop的关键

我们通过Proxy.newProxyInstance方法创建的proxy对象在执行方法时,全部会通过PersonInvocationHandler中的invoke方法,在上面没有介绍的invoke方法中的Object proxy参数即为此处创建的proxy对象。

这样一来我们就实现了一个简单的动态代理,如果你要处理更复杂业务,只需要添加相应的业务代码到InvocationHandler中的invoke方法中便能实现。

虽然jdk动态代理已经很好用了,但我们有时候没有实现接口该怎么办呢,此时就需要请出cglib动态代理了。

cglib动态代理不再是创建实现了指定借口的对象了,而是创建继承了指定类的对象:

public class Test {
	public static void main(String[] args) {
		Enhancer en = new Enhancer();
		en.setSuperclass(Person.class);
		en.setCallback( new CGlibProxy() );   
		Person p = (Person) en.create();
		p.action();
	}
}
Enhancer翻译过来即为增强器,相当于jdk动态代理中的Proxy类,同样是用于创建代理对象,

setSuperclass(Class<?> clazz)用于指定需要继承的类。

setCallback(Callback callback)用于指定处理器。

在cglib中也有处理器,不过名字却叫做拦截器了,如下所示,实现了MethodInterceptor接口:

public class CGlibProxy implements MethodInterceptor {
	@Override
	public Object intercept(Object object, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		
		System.out.println("前置事件");		
		Object result = methodProxy.invokeSuper(object, args);		
		System.out.println("后置事件");		
		return result;

	}
}
内部有一个需要实现的方法intercept Object object:通过Enhancer创建的代理对象。 Method method:目标方法的反射对象。 Object[] args:调用方法的参数。 MethodProxy:用来代替method的一个参数,可以调用父类的方法,如果使用method.invoke(object, args)的话,调用的还是我们创建的代理对象的方法,会发生无限递归。     到此为止应该就有了一个Aop的基本理解了,接下来可以试一下多个回调类,网上也有很多的博客能够学习,在这里我也贴一个吧 http://www.blogjava.net/stone2083/archive/2008/03/16/186615.html

猜你喜欢

转载自zk-chs.iteye.com/blog/2266685