代理的作用:在客户端和目标对象之间起到中介的作用
代理的目的:尽可能隐藏自己,对目标方法增强(不修改源代码)
静态代理:
需要自己写代理对象
想代理一个对象,需要和目标对象有相同的行为(方法),借助实现相同接口的方式实现
package com.buka.java.designMode.agent;
//代理接口
public interface IN {
void eat();
void show();
}
package com.buka.java.designMode.agent;
//调用者
public class XMQ {
public static void main(String[] args) {
WP wp = new WP(new PJL());
wp.eat();
}
}
package com.buka.java.designMode.agent;
//代理对象
public class WP implements IN{
private IN people;
//构造方法实现对不同目标对象的代理
public WP(IN in) {
this.people = in;
}
@Override
public void eat() {
System.out.println("WP 订饭店");
people.eat();
System.out.println("WP 买单");
}
@Override
public void show() {
people.show();
}
}
package com.buka.java.designMode.agent;
//目标对象1
public class PJL implements IN{
public void eat() {
System.out.println("PJL eat...");
}
@Override
public void show() {
System.out.println("PJL show...");
}
}
package com.buka.java.designMode.agent;
//目标对象2
public class LPE implements IN{
@Override
public void eat() {
System.out.println("LPE eat...");
}
@Override
public void show() {
System.out.println("LPE show...");
}
}
动态代理(常用的代理):
jdk自动生成代理对象,基于接口,必须有接口
将静态代理中WP类删除,XMQ类改为如下代码即可实现同样的功能
package com.buka.java.designMode.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//调用者
public class XMQ {
public static void main(String[] args) {
//目标对象
IN pjl = new PJL();
//生成代理对象 三个参数:目标对象的类加载器,目标对象的接口,具体策略
IN o = (IN)Proxy.newProxyInstance(
pjl.getClass().getClassLoader(),
pjl.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk 订饭店");
method.invoke(pjl);
System.out.println("jdk 买单");
return null;
}
});
o.eat();
}
}
对于有返回值及形参的方法
package com.buka.java.designMode.agent;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//调用者
public class XMQ {
public static void main(String[] args) {
//目标对象
IN pjl = new PJL();
//生成代理对象 三个参数:目标对象的类加载器,目标对象的接口,具体策略
IN o = (IN)Proxy.newProxyInstance(
pjl.getClass().getClassLoader(),
pjl.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("jdk 订饭店");
//args是参数数组,只写args即可
int i = (int)method.invoke(pjl,args);
System.out.println("jdk 买单");
return i;
}
});
//有几个参数写几个
int eat = o.eat(100);
System.out.println(eat);
}
}