动态代理
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();
}