静态代理实现步骤:
-
定义一个接口及其实现类;
-
创建一个代理类同样实现这个接口
-
将目标对象注入进代理类,然后在代理类的对应方法调用目标类中的对应方法。这样的话,我们就可以通过代理类屏蔽对目标对象的访问,并且可以在目标方法执行前后做一些自己想做的事情。
1、接口、实现类
/**
* TODO 待代理对象、定义对象的行为
*
* @author LinFH
* @version 1.0
* @date 2021-03-03 16:13
*/
public interface SingerInterface {
/**
* 根据歌名点歌
*
* @param songName
*/
public String orderSong(String songName);
/**
* 向观众告别
*
* @param audienceName
*/
public String sayGoodBye(String audienceName);
}
/**
* TODO
*
* @author LinFH
* @version 1.0
* @date 2021-03-03 16:17
*/
public class WangLiHong implements SingerInterface {
@Override
public String orderSong(String songName) {
// TODO Auto-generated method stub
System.out.println("演唱歌曲:" + songName);
return "";
}
@Override
public String sayGoodBye(String audienceName) {
// TODO Auto-generated method stub
System.out.println("再见:" + audienceName);
return "";
}
@Override
public String toString() {
return "WangLiHong{}";
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
}
2、创建一个代理类同样实现这个接口
/**
* TODO
*
* @author LinFH
* @version 1.0
* @date 2021-03-03 16:18
*/
public class MyStoryInvocationHandler implements InvocationHandler {
private Object object;
private String name;
public MyStoryInvocationHandler(Object o) {
// TODO Auto-generated constructor stub
this.object = o;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
// TODO Auto-generated method stub
System.out.println("力宏,我是你代理经纪人:" + proxy.getClass().getName());
//处理业务
System.out.println("巴拉巴拉......(讲了一个故事)");
for (Object arg : args) {
System.out.println("传入的参数:" + arg);
}
//通过反射机制,通知力宏做事情
Object invoke = method.invoke(object, args);
//处理业务
System.out.println("巴拉巴拉,感谢........");
return null;
}
@Override
public String toString() {
return "MyStoryInvocationHandler{" +
"object=" + object +
", name='" + name + '\'' +
'}';
}
}
3、测试
// 常规测试
public static void main(String[] args) {
//实例化目标对象(创造一个力宏)
WangLiHong liHong = new WangLiHong();
//实例化调用处理类(编好的故事)
MyStoryInvocationHandler handler = new MyStoryInvocationHandler(liHong);
//接下来创建代理(经纪人)
//准备一个类加载器
ClassLoader loader = MyStoryInvocationHandler.class.getClassLoader();
//获取目标对象的接口类对象数组
Class<?>[] interfaces = liHong.getClass().getInterfaces();
//创建代理
SingerInterface proxy = (SingerInterface) Proxy.newProxyInstance(loader, interfaces, handler);
//开始点歌
String s1 = proxy.orderSong("就是现在");
System.out.println("****** 歌唱中......********");
//歌唱完了,say goodBye吧
String s2 = proxy.sayGoodBye("zhangchengzi");
System.out.println("proxy.equals(handler) = " + proxy.equals(handler));
System.out.println("proxy = " + proxy);
System.out.println("s1 = " + s1);
System.out.println("s2 = " + s2);
}
测试 验证 JDK 代理能否类
@Test
public void testProxyClass() {
// 代理 类
final ClassLoader classLoader = TestProxy.class.getClassLoader();
final MapperProxy mapperProxy = new MapperProxy();
WangLiHong wangLiHong = (WangLiHong) Proxy.newProxyInstance(classLoader, new Class[]{WangLiHong.class}, mapperProxy);
String hhhh = wangLiHong.orderSong("hhhh");
System.out.println("hhhh = " + hhhh);
}
异常: java.lang.IllegalArgumentException: xxxx.WangLiHong is not an interface