动态代理(AOP)和装饰者模式有点像

动态代理

1. 只学一个方法
方法的作用:在运行时,动态创建一组指定的接口的实现类对象!(在运行时,创建实现了指定的

Object proxyObject = Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces,

InvocationHandler h);

interfaces 它实现了A和B类的对象
1. 方法作用:proxyObject会实现 Class[] interfaces 这里面所有给定接口
参数;
1. ClassLoader:类加载器!
  * 它是用来加载器的,把.class文件加载到内存,形成Class对象!


2. Class[] interfaces:指定要实现的接口们
3. InvocationHandler:代理对象的所有方法(个别不执行,getClass())都会调用InvocationHandler

的invoke()方法。

package cn.itcast.demo1;

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

import org.junit.Test;

public class Demo1 {
	@Test
	public void fun1() {
		/*
		 * 三大参数
		 * 1. ClassLoader
		 * 方法需要动态生成一个类,这个类实现了A、B接口,然后创建这个类的对象!
		 * 需要生成一个类,这个类也需要加载到方法区中,谁来加载,当然是ClassLoader!!!
		 * 
		 * 2. Class[] interfaces
		 * 它是要实现的接口们
		 * 
		 * 3. InvocationHandler
		 * 它是调用处理器
		 * 敷衍它!
		 * 
		 * 代理对象的实现的所有接口中的方法,内容都是调用InvocationHandler的invoke()方法。
		 */
		ClassLoader loader = this.getClass().getClassLoader();//这个类的对象也知道是谁加载了我
		InvocationHandler h = new InvocationHandler() {
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				System.out.println("你好,动态代理!");
				return "xxx";
			}
		};
		// 使用三大参数创建代理对象!!!
		Object o = Proxy.newProxyInstance(loader, new Class[]{A.class, B.class}, h);
		
		// 强转成A和B类型,成功了!
		A a = (A) o;
		B b = (B) o;
		
//		a.a();
//		a.aa();
//		b.b();
//		b.bb();
		
//		System.out.println(o.getClass().getName());
		
		Object result = a.aaa("hello", 100);
		System.out.println(result);
	}
}

interface A {
	public void a();
	public void aa();
	public Object aaa(String s, int i);
}

interface B {
	public void b();
	public void bb();
}
你好,动态代理!
你好,动态代理!
你好,动态代理!
你好,动态代理!
cn.itcast.demo1.$Proxy4
你好,动态代理!
xxx

DEMO2

package cn.itcast.demo2;

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

import org.junit.Test;

/**
 * 我们必须要掌握的是当前这个案例!
 * @author cxf
 *
 */
public class Demo2 {
	@Test
	public void fun1() {
		Waiter manWaiter = new ManWaiter();//目标对象
		/*
		 * 给出三个参数,来创建方法,得到代理对象
		 */
		ClassLoader loader = this.getClass().getClassLoader();
		Class[] interfaces = {Waiter.class};
		InvocationHandler h = new WaiterInvocationHandler(manWaiter);//参数manWaiter表示目标对象
		// 得到代理对象,代理对象就是在目标对象的基础上进行了增强的对象!
		Waiter waiterProxy = (Waiter)Proxy.newProxyInstance(loader, interfaces, h);
		
		waiterProxy.serve();//前面添加“您好”, 后面添加“再见”
	}
}

class WaiterInvocationHandler implements InvocationHandler {
	private Waiter waiter;//目标对象
	
	public WaiterInvocationHandler(Waiter waiter) {
		this.waiter = waiter;
	}
	
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("您好!");
		this.waiter.serve();//调用目标对象的目标方法
		System.out.println("再见!");
		return null;
	}
}
package cn.itcast.demo2;

public class ManWaiter implements Waiter {
	public void serve() {
		System.out.println("服务中...");
	}
}
package cn.itcast.demo2;

// 服务员
public interface Waiter {
	// 服务
	public void serve();
}


---------------------------------------------------------

2. 动态代理作用
  最终是学习AOP(面向切面编程),它与装饰者模式有点相似,它比装饰者模式还要灵活!

目标对象:被增强的对象
代理对象:需要目标对象,然后在目标对象上添加了增强后的对象!
目标方法:增强的内容

代理对象 = 目标对象 + 增强

InvocationHandler

public Object invoke(Object proxy, Method method, Object[] args);

这个invoke()方法在什么时候被调用!
1. 在代理对象被创建时?错误的!
2. 在调用代理对象所实现接口中的方法时?正确的!

* Object proxy:当前对象,即代理对象!在调用谁的方法!
* Method method:当前被调用的方法(目标方法)
* Object[] args:实参!

----------------------------

package cn.itcast.demo3;

import org.junit.Test;

/*
 * 目标是让目标对象和增强都可以切换!
 */
public class Demo3 {
	@Test
	public void fun1() {
		ProxyFactory factory = new ProxyFactory();//创建工厂
		factory.setTargetObject(new ManWaiter());//设置目标对象
		factory.setBeforeAdvice(new BeforeAdvice() {//设置前置增强
			public void before() {
				System.out.println("您好不好!");
			}
		});
		
		factory.setAfterAdvice(new AfterAdvice() {//设置后置增强
			public void after() {
				System.out.println("再见不见!");
			}
		});
		
		Waiter waiter = (Waiter)factory.createProxy();
		waiter.shouQian();
	}
	
	public void zhuanZhang() {
		/*
		 * 1.
		 * 2. 
		 * 3. 
		 */
	}
}
package cn.itcast.demo3;

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

/**
 * 它用来生成代理对象
 * 它需要所有的参数
 * * 目标对象
 * * 增强
 * @author cxf
 */
/**
 * 1. 创建代理工厂
 * 2. 给工厂设置三样东西:
 *   * 目标对象:setTargetObject(xxx);
 *   * 前置增强:setBeforeAdvice(该接口的实现)
 *   * 后置增强:setAfterAdvice(该接口的实现)
 * 3. 调用createProxy()得到代理对象
 *   * 执行代理对象方法时:
 *   > 执行BeforeAdvice的before()
 *   > 目标对象的目标方法
 *   > 执行AfterAdvice的after()
 * @author cxf
 *
 */
public class ProxyFactory {
	private Object targetObject;//目标对象
	private BeforeAdvice beforeAdvice;//前置增强
	private AfterAdvice afterAdvice;//后置增强
	
	
	/**
	 * 用来生成代理对象
	 * @return
	 */
	public Object createProxy() {
		/*
		 * 1. 给出三大参数
		 */
		ClassLoader loader = this.getClass().getClassLoader();
		Class[] interfaces = targetObject.getClass().getInterfaces();
		InvocationHandler h = new InvocationHandler() {
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				/*
				 * 在调用代理对象的方法时会执行这里的内容
				 */
				// 执行前置增强
				if(beforeAdvice != null) {
					beforeAdvice.before();
				}
				
				Object result = method.invoke(targetObject, args);//执行目标对象的目标方法
				// 执行后置增强
				if(afterAdvice != null) {
					afterAdvice.after();
				}
				
				// 返回目标对象的返回值
				return result;
			}
		};
		/*
		 * 2. 得到代理对象
		 */
		Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
		return proxyObject;
	}
	
	
	public Object getTargetObject() {
		return targetObject;
	}
	public void setTargetObject(Object targetObject) {
		this.targetObject = targetObject;
	}
	public BeforeAdvice getBeforeAdvice() {
		return beforeAdvice;
	}
	public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
		this.beforeAdvice = beforeAdvice;
	}
	public AfterAdvice getAfterAdvice() {
		return afterAdvice;
	}
	public void setAfterAdvice(AfterAdvice afterAdvice) {
		this.afterAdvice = afterAdvice;
	}
}
package cn.itcast.demo3;

// 服务员
public interface Waiter {
	// 服务
	public void serve();
	
	public void shouQian();
}
package cn.itcast.demo3;

public class ManWaiter implements Waiter {
	public void serve() {
		System.out.println("服务中...");
	}
	
	public void shouQian() {
		System.out.println("混蛋,给我钱!");
	}
}
package cn.itcast.demo3;

public interface AfterAdvice {
	public void after();
}
package cn.itcast.demo3;

/**
 * 前置增强
 * @author cxf
 *
 */
public interface BeforeAdvice {
	public void before();
}

猜你喜欢

转载自blog.csdn.net/qq_20610631/article/details/81160115