java动态代理(知识点扫盲)

动态代理就先说代理模式,然后是动态代理

代理模式中,会有代理对象,和被代理对象(目标业务对象)。代理对象会拦截对目标业务对象的访问。类似于现实中的明星和经纪人。

/*
* 明星的接口
*/
public interface SuperStar {
public void sing(double money);
public void liveShow(double money);
public void sleep();
}
/*
* 一个具体的明星:黄渤
*/
public class HuangBo implements SuperStar {
@Override
public void sing(double money) {
System.out.println("黄渤唱了一首歌!");
System.out.println("黄渤赚了" + money + "RMB");
}
@Override
public void liveShow(double money) {
System.out.println("黄渤参加极限挑战!");
System.out.println("黄渤赚了" + money + "RMB");
}
@Override
public void sleep() {
System.out.println("黄渤太累了。。。休息一会儿");
}
}

/*
* 代理类A,代理黄渤
*/
public class A implements SuperStar {
// 持有真实业务对象
private SuperStar s;

// 接收真实业务对象
public A(SuperStar s) {
this.s = s;
}

@Override
public void sing(double money) {
// 做一个拦截
if (money < 100000) {
System.out.println("钱太少,不去");
return;
}
System.out.println("A抽取" + money * 0.6 + "提成");
s.sing(money * 0.4);
}

@Override
public void liveShow(double money) {
// 做一个拦截
if (money < 500000) {
System.out.println("钱太少,加钱!");
return;
}
System.out.println("A抽取" + money * 0.6 + "提成");
s.liveShow(money * 0.4);
}

@Override
public void sleep() {
System.out.println("帮忙定个酒店。。。");
s.sleep();
}
}
/** 演示:代理模式* 代理:代理对象主要用来拦截目标业务对象(被代理对象)的访问。*  A:代理对象要持有真实业务对象。(通过构造函数接收业务对象,并用成员变量记录)*  B:代理对象要和真实业务对象,具备相同的行为方法(实现相同接口)*  C:代理对象拦截对真实对象的访问,可以修改访问的参数、返回值,甚至拦截访问* 代理模式与装饰模式区别*  A:代理模式侧重与拦截,装饰模式侧重与加强*  B:Java中自带的代理中,只能对接口进行代理。装饰只需要与被装饰类有共同父类。*/public class ProxyDemo01 {
public static void main(String[] args) {
// 创建被代理对象
HuangBo huangBo = new HuangBo();
// 创建代理对象
A  a= new A(huangBo);

// 访问方法
a.sing(500);
System.out.println("----------");
a.liveShow(1000000);
System.out.println("----------");
a.sleep();
}
}

下面动态代理

java动态代理(知识点扫盲)


/** 演示:动态代理
* 动态代理:在程序运行过程中产生的一个代理对象
* 在程序运行的过程中,动态在内存中生成一个类,代理需要被代理的目标对象,并且生成这个代理类的对象。
* Java如何凭空生成一个代理类,并且代理黄渤的呢?我们要查看一个API:
*  static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
*   ClassLoader loader :类加载器,一般用被代理对象的类加载器
*   Class[] interfaces : 被代理对象的接口的Class对象数组,Class<?>[] getInterfaces()  
*   InvocationHandler h : 调用处理器
*/
public class ProxyDemo02 {
public static void main(String[] args) {
// 创建被代理对象
final HuangBo huangBo = new HuangBo();
// 先准备动态代理的三大参数
// 被代理类的类加载器
ClassLoader loader =huangBo .getClass().getClassLoader();
// 被代理对象的接口的Class对象数组
Class<?>[] interfaces =huangBo .getClass().getInterfaces();
//huangBo .getClass().getInterfaces();{SuperStar.class}
// 调用处理器
InvocationHandler h = new InvocationHandler(){
// 当我们调用代理对象的功能时,代理对象,其实都来调用了处理器中的invoke功能
// 因此,我们需要在invoke中写拦截的逻辑!
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Object proxy : 是代理对象本身
// Method method :当前正在被调用的真实方法的对象
// Object[] args : 当前正在被调用的真实方法的真实参数
String name = method.getName();
// 判断方法的名称,做出不同的拦截逻辑
if( "sing".equals(name) || "liveShow".equals(name)){
double money = (double) args[0];
double min = "sing".equals(name) ? 100000 : 500000;
if (money < min) {System.out.println("钱太少,不去");
return null;}System.out.println("A抽取" + money * 0.6 + "提成");
return method.invoke(huangBo, money * 0.4);
}
return method.invoke(huangBo, args);}};
// static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
SuperStar p = (SuperStar) Proxy.newProxyInstance(loader, interfaces, h);
p.sing(100);p.liveShow(1000000);p.sleep();}}

猜你喜欢

转载自blog.51cto.com/4534309/2107075