【Aop】Aop中的动态代理

动态代理主要分为两种:1、基于接口的动态代理;2、基于子类的动态代理;接下来就对这两种代理方式的使用进行介绍。

1、基于接口的动态代理

IActor 接口:

public interface IActor {
	/**
	 * 基本表演
	 * @param money
	 */
	public void basicAct(float money);

	/**
	 * 危险的表演
	 * @param money
	 */
	public void dangerAct(float money);
}

Actor类:

public class Actor implements IActor {
	/**
	 * 基本表演
	 * @param money
	 */
	public void basicAct(float money) {
		System.out.println("开始基本表演:" + money);
	}

	/**
	 * 危险的表演
	 * @param money
	 */
	public void dangerAct(float money) {
		System.out.println("开始危险表演:" + money);
	}
}

Client:

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

public class Client {
	/**
	 * 模拟一个剧组
	 * @param args
	 */
	public static void main(String[] args) {
		final Actor actor=new Actor();
		/**
		 * 动态代理:
		 * 		作用:再不改变源码的基础上,对已有的方法进行增强(它是AOP思想的实现技术)
		 * 		分类:
		 * 			1)基于接口的动态代理
		 * 						要求:被代理类最少实现一个接口。
		 * 						提供者:JDK官方
		 * 						涉及的类:Proxy
		 * 			创建代理对象的方法:newProxyInstance(ClassLoader, Class[], InvocationHandler)
		 * 				参数含义:ClassLoader:类加载器;和被代理对象使用相同的类加载器。一般固定写法
		 * 						Class[]:字节码数组。被代理类实现的接口。(要求代理对象与被代理对象具有相同的行为)
		 * 						InvocationHandler(策略模式):一个接口,用于提供增强代码的。一般写一个该接口的实现类。实现类可以为匿名内部类。
		 * 							策略模式:
		 * 								使用要求:数据已经有了、目的明确、达成目标的过程就是策略。
		 * 								 在dbutils中的ResultSetHandler就是策略的具体应用。 
		 */												
		IActor proxyActor=(IActor) Proxy.newProxyInstance(actor.getClass().getClassLoader(), 
				actor.getClass().getInterfaces(), new InvocationHandler() {
					/**
					 * 执行被代理对象的任何方法都会经过该方法,该方法有拦截功能。
					 * 方法参数:
					 * 		Object proxy:代理对象的引用。不一定每次都会用
					 * 		Method method:当前执行的方法。
					 * 		Object[] args:当前执行方法所需的参数。
					 * 返回值:当前执行方法的返回值。
					 * 		
					 */
					
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						Object rtValue=null;
						//1、取出执行方法中的参数
						Float money=(Float) args[0];
						//2、判断当前执行的是什么方法
						if ("basicAct".equals(method.getName())) {
							//基本演出
							if (money>10000) {
								//执行方法
								rtValue=method.invoke(actor, args);
							}else {
								System.out.println("给钱太少,不能表演!");
							}
						}
						if ("dangerAct".equals(method.getName())) {
							//危险演出
							if (money>50000) {
								//执行方法
								rtValue=method.invoke(actor, args);
							}else {
								System.out.println("给钱太少,不能表演!");
							}
						}
						return rtValue;
					}
				});
		proxyActor.basicAct(10000f);
		proxyActor.dangerAct(60000f);
	}
}
2、基于子类的动态代理

IActor接口和Actor类与第一种情况一致,这里就不赘述了;
Client:

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

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import proxy.IActor;

public class Client {

	/**
	 * 模拟一个剧组
	 * @param args
	 */
	public static void main(String[] args) {
		final Actor actor=new Actor();
		/**
		 * 动态代理:
		 * 		作用:再不改变源码的基础上,对已有的方法进行增强(它是AOP思想的实现技术)
		 * 			2)基于子类的动态代理:
		 * 						需要用到的两个jar包:
		 * 										1)asm-4.0.jar
		 * 										2)cglib-2.2.1.jar
		 * 						要求:被代理的类不能是最终类。 不能被final修饰。
		 * 						提供者:第三方CGLib
		 * 						涉及的类:Enhancer
		 * 						创建代理对象的方法:create(Class,Callback);
		 * 						参数的含义:
		 * 								Class:被代理对象的字节码 
		 * 								Callback:如何代理,也是一个接口,我们一般使用该接口的子接口;与InvocationHandler作用一样。
		 */	
		Actor cglibActor=(Actor) Enhancer.create(actor.getClass(),new MethodInterceptor(){
			/**
			 * 执行被代理对象的任何方法都会经过该方法,该方法有拦截功能。
			 * 方法的参数:
			 * 			前面三个和invoke方法的参数含义和作用都一样。
			 * 			MethodProxy methodProxy:当前执行方法的代理对象。一般不用
			 * 
			 */
			@Override
			public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
				
				Object rtValue=null;
				//1、取出执行方法中的参数
				Float money=(Float)args[0];
				//2、判断当前执行的是什么方法
				if ("basicAct".equals(method.getName())) {
					//基本演出
					if (money>10000) {
						//执行方法
						rtValue=method.invoke(actor, args);
					}
				}
				if ("dangerAct".equals(method.getName())) {
					//危险演出
					if (money>50000) {
						//执行方法
						rtValue=method.invoke(actor, args);
					}
				}
				return rtValue;
			}			
		});
		cglibActor.basicAct(50000f);
		cglibActor.basicAct(100000f);
	}
}
发布了66 篇原创文章 · 获赞 6 · 访问量 9432

猜你喜欢

转载自blog.csdn.net/qgnczmnmn/article/details/102483950