动态代理

java.lang.reflect.Proxy :Prpxy.newProxyInstance()

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException

>方法作用:动态创建 实现了interfaces数组中所有指定接口的 实现类对象。

(该方法动态生成一个类,该类实现了接口数组中的所有接口,最后创建这个类的对象。以前都是专门写一个class类,然后在main方法中new一个对象。而现在是通过一个方法来创建类,根据实现的接口不同,创建出的类也不同,这也是“动态”的体现)

>参数:

     1.ClassLoader:类加载器。用来加载类,将.class文件加载到内存中,形成Class对象。

         Java中通过Person p = new Person();来创建对象。实际创建对象的过程中有以下流程:

         ①通过ClassLoader将Person.class加载到内存中,将其变成Class<Person>对象;然后执行静态代码块和静态初始化语句

         ②执行new方法,创建一个空白对象

         ③调用构造器

         ④子类调用父类构造器

         ⑤构造器执行过程:执行构造器代码块和初始化语句;然后执行构造器中内容

    2.Class[ ]  interfaces:指定要实现的接口数组

    3.InvocationHandler:代理对象的所有方法(个别不执行) ,内容都是调用InvocationHandler中的invoke()方法

 

InvocationHandler h = new InvocationHandler() {
			
			public Object invoke(Object arg0, Method arg1, Object[] arg2)
					throws Throwable {
				return null;
			}
		};

invoke()方法在调用代理对象所实现的接口中的方法时被调用。

可以从中找出关系,当返回的代理对象在调用接口中的方法时,会自动调用InvocationHandler中的invoke()方法,此时,将代理对象赋值给invoke参数中的proxy;aaa方法赋值给参数method;方法中的参数赋值给args。此时invoke返回的Object赋值给result

>参数:

          1.Object proxy:当前代理对象

          2.Method method:当前被当用的方法

          3.Object[] args:实参

 

 

public interface Waiter {
	public void service();
}
public class ManWaiter implements Waiter {

	public void service() {
		System.out.println("服务");

	}

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


public class Demo2 {

	public void fun(){
		Waiter manWaiter = new ManWaiter();
		
		//给出三个参数来创建动态代理对象
		ClassLoader loader = this.getClass().getClassLoader();
		Class[] interfaces = {Waiter.class};
		InvocationHandler h = new WaiterInvocationHandler(manWaiter);
		
		//得到代理对象,代理对象实质就是在目标对象的基础上进行增强
		Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(loader, interfaces, h); 
		waiterProxy.service();
		
	}
}

class WaiterInvocationHandler implements InvocationHandler{
	private Waiter waiter;//目标对象
	
	public WaiterInvocationHandler(Waiter waiter){
		this.waiter = waiter;
	}
	ManWaiter manWaiter = new ManWaiter();
	public Object invoke(Object arg0, Method arg1, Object[] arg2)
			throws Throwable {
		System.out.println("上菜");
		waiter.service();
		System.out.println("收小费");
		return null;
	}
	
}

举例:给一个计算器添加日志管理。

public interface Calculator {

	public int add(int i,int j);
	public int sub(int i,int j);
	public int mul(int i,int j);
	public int div(int i,int j);
	
}
import com.cuco.inter.Calculator;

public class MyMathCalculator implements Calculator {

	public int add(int i, int j) {
		// TODO Auto-generated method stub
		return i+j;
	}

	public int sub(int i, int j) {
		// TODO Auto-generated method stub
		return i-j;
	}

	public int mul(int i, int j) {
		// TODO Auto-generated method stub
		return i*j;
	}

	public int div(int i, int j) {
		// TODO Auto-generated method stub
		return i/j;
	}

}
/*
 * 为Calculator.java生成代理对象的类
 * 
 * */
public class CalculatorProxy {

	public static Calculator getProxy(final Calculator calculator){
		//为传入的对象创建动态代理对象
		
		//方法执行器,帮目标对象执行目标方法
		InvocationHandler h = new InvocationHandler(){
			/*
			 * Object proxy:代理对象:给JDK使用,任何时候不要使用该对象
			 * Method method:当前将要执行目标对象的方法
			 * Object[] args:方法调用时,外界传入的实参
			 * */
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				
				//利用反射执行目标方法
				//目标方法执行后的返回值
				LogUtils.logStart(method, args);
				Object result =	method.invoke(calculator, args);
				LogUtils.logReturn(method, result);
				return result;
			}
			
		};
		Class<?>[] interfaces = calculator.getClass().getInterfaces();
		ClassLoader loader = calculator.getClass().getClassLoader(); //目标对象的类加载器
		
		Object proxy = Proxy.newProxyInstance(loader,interfaces,h);
		return (Calculator)proxy;
		
		
	}
			
}
public class LogUtils {

	public static void logStart(Method method, Object[] args){
		System.out.println("["+method.getName()+"]方法开始执行,使用参数列表["+Arrays.asList(args)+"]");
	}
	public static void logReturn(Method method, Object result){
		System.out.println("["+method.getName()+"]方法执行结束,执行结果为["+result+"]");
	}
}
public class AOPTest {
/*
 * 有了动态代理:日志记录可以更加强大,不需要将日志记录放在执行方法中,和业务逻辑解耦
 * 
 * */
	@Test
	public void test() {
		
	Calculator calculator = new MyMathCalculator();
	calculator.add(2, 4);
	System.out.println("-------------------------------------------");
	
	Calculator proxy = CalculatorProxy.getProxy(calculator);
	proxy.add(5, 6);
	
	
	}

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值