Java手写动态代理(支持多个切面)

1.目标类

package com.hqa.test;
import com.hqa.annotion.Aop;

public class TestAop{

	@Aop(executeValue="com.hqa.test.TestAopHandler")
	public void print(){

		System.out.println("AOP method print executed=======================>>>");

	}
	@Aop(executeValue="com.hqa.test.TestAopHandler")
	public void printNoAop(){

		System.out.println("No-AOP method print executed=======================>>>");

	}
	
	public void printNoAop2(){

		System.out.println("No-AOP2 method print executed=======================>>>");

	}
	
	

}

2.切面父类

package com.hqa.test;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodProxy;

public abstract class Handler {

	public abstract void before(MethodProxy proxy,Object o,Object[] args,Method method);
	
	public abstract void around(MethodProxy proxy,Object o,Object[] args,Method method);
	
	public abstract void after(MethodProxy proxy,Object o,Object[] args,Method method);
	
	public abstract void exception(MethodProxy proxy,Object o,Object[] args,Method method);
	
	public abstract void returns(MethodProxy proxy,Object o,Object[] args,Method method,Object results);
	
	final  Object execute(MethodProxy proxy,Object o,Object[] args,Method method){
		
		Object ret = null;
		try {
			ret = proxy.invokeSuper(o, args);
		} catch (Throwable e) {
			e.printStackTrace();
			exception(proxy, o, args, method);
		}  
		
		return ret;
	}
	
}

3.自定义切面

package com.hqa.test;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodProxy;

public class TestAopHandler extends Handler{

	@Override
	public void before(MethodProxy proxy, Object o, Object[] args, Method method) {
		System.out.println("***********************************>>前置通知<<**************************************");
		
	}

	@Override
	public void around(MethodProxy proxy, Object o, Object[] args, Method method) {
		System.out.println("***********************************>>环绕通知<<**************************************");
	}

	@Override
	public void after(MethodProxy proxy, Object o, Object[] args, Method method) {
		System.out.println("***********************************>>前置通知<<**************************************");
	}

	@Override
	public void exception(MethodProxy proxy, Object o, Object[] args,
			Method method) {
		System.out.println("***********************************>>异常通知<<**************************************");
	}

	@Override
	public void returns(MethodProxy proxy, Object o, Object[] args,
			Method method, Object results) {
		System.out.println("***********************************>>返回通知<<**************************************");
	}

}

4.代理类工厂

package com.hqa.test;
import java.util.ArrayList;
import java.util.List;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.NoOp;

public class ProxyCreator {
	private List<MyInterceptor> interceptors = new ArrayList<MyInterceptor>();
	private List<Callback> callbacks = new ArrayList<Callback>();
	public  void addInterceptor(MyInterceptor interceptor){
		interceptors.add(interceptor);
	}
	public  Object getInstance(Object target) {  
		Enhancer enhancer = new Enhancer();  
		enhancer.setSuperclass(target.getClass());  
		callbacks.add(NoOp.INSTANCE);
		for(int i = 0 ; i < interceptors.size() ; i++ ){
				callbacks.add(interceptors.get(i));
		}


		// 回调方法  
		Callback[] c = new Callback[callbacks.size()];
		int i = 0;
		for (Callback callback : callbacks) {
			c[i] = callback;
			i ++;
		}
		enhancer.setCallbacks(c);  
		enhancer.setCallbackFilter(new CallbackFilterImpl(callbacks));
		// 创建代理对象  
		return enhancer.create();  
	}  
}

5.代理拦截器

package com.hqa.test;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import com.hqa.annotion.Aop;

public class MyInterceptor implements MethodInterceptor {  
	private Handler aopHandler;
	public Handler getAopHandler() {
		return aopHandler;
	}
	public MyInterceptor( Handler aopHandler){
		this.aopHandler = aopHandler;
	}

	@Override  
	// 回调方法  
	public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,  
			MethodProxy proxy) throws Throwable {  
		Aop aop = method.getAnnotation(Aop.class);
		if(aop == null) {
			Object ret = proxy.invokeSuper(obj, args);  
			return ret;
		}
		aopHandler.before(proxy, obj, args, method);
		aopHandler.around(proxy, obj, args, method);
		Object ret = aopHandler.execute(proxy, obj, args, method);
		aopHandler.around(proxy, obj, args, method);
		aopHandler.after(proxy, obj, args, method);
		aopHandler.returns(proxy, obj, args, method,ret);
		return ret;  

	}

	public Handler getHandler() {
		return aopHandler;
	}

	public void setHandler(Handler handler) {
		this.aopHandler = handler;
	}  

}

6.代理类过滤器

package com.hqa.test;
import java.lang.reflect.Method;
import java.util.List;
import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter;
import com.hqa.annotion.Aop;

public class CallbackFilterImpl implements CallbackFilter{

	private List<Callback> callbacks;

	@Override
	public int accept(Method method) {
		Aop proxy = method.getAnnotation(Aop.class);
		if(proxy==null){
			return 0;
		}
		String val = proxy.executeValue();
		int ret = 0;
		int index = 0;
		for (Callback callback : callbacks) {
			if(callback instanceof MyInterceptor){
				Class<? extends Handler> clazz = ((MyInterceptor)callback).getHandler().getClass();
				if(clazz.getName().equals(val)){
					ret = index;
					break;
				}

			}
			index++;
		}
		System.out.println(val+"---+++>>"+ret);

		return ret;

	}

	public CallbackFilterImpl(List<Callback> callbacks){
		this.callbacks = callbacks;
	}
	public CallbackFilterImpl(){
	}

}

7.测试主方法

package com.hqa.test;
public class Test {

	public static void main(String[] args){
		TestAop ta = new TestAop();
		ProxyCreator pc = new ProxyCreator();
		pc.addInterceptor(new MyInterceptor(new TestAopHandler()));
		Object instance = pc.getInstance(ta);
		long a = System.currentTimeMillis();
		((TestAop)instance).print();
		System.out.println("============>"+(System.currentTimeMillis() - a)+"ms");
		long b = System.currentTimeMillis();
		((TestAop)instance).printNoAop();
		System.out.println("============>"+(System.currentTimeMillis() - b)+"ms");
		long c = System.currentTimeMillis();
		((TestAop)instance).printNoAop2();
		System.out.println("============>"+(System.currentTimeMillis() - c)+"ms");
	}
}

8.自定义切面注解

package com.hqa.annotion;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(value={ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Aop {
	//此是目标切面全类名
	public String executeValue();
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值