加入你刚进入一座陌生的城市,这时候你要找个房子,找房子就肯定得联系房东,但是茫茫人海,你并不知道哪一位才是你的房东,这时候你可以寻找一位中介,让中介给你房源,和中介签一些协议,付款等一系列操作,假如没有中介,你需要和房东签合同,付款,房东可能没有那么多心思和你来谈生意,所以他们把房子的信息交给中介,该让房东出面的时候中介去联系,你只需要和中介打交道。这里的中介就相当于代理,这种思想就是动态代理思想。
理解动态代理的两个类和一个接口:
Proxy:类,用法:Proxy.newProxyInstance() ,创建目标对象的代理对象;
Method:类,用法:method.invoke(target,args),真正的额执行目标方法;
InvocationHandler:接口,编写的代理对象需要实现该接口,重写接口中的方法invoke(),实现功能的增强。
先上代码,
先定义service接口,使用JDK的动态代理模式,接口必须要有,这是java设计上的额要求。
public interface Service {
void doSome(String name,int age);
void doOther();
}
service的实现类
public class ServiceImpl implements Service {
@Override
public void doSome(String name,int age) {
System.out.println("doSome()方法执行"+name+" "+age );
}
@Override
public void doOther() {
System.out.println("doOther()方法执行");
}
}
然后编写代理类,普通类实现InvocationHandler接口便成了代理类
//这里的MyInvocationHandler相当于联系的中介
public class MyInvocationHandler implements InvocationHandler {
//需要声明你的目标对象,就像房东主人
private Object target;
//定义有参构造方法
public MyInvocationHandler(Object target) {
this.target = target;
}
public MyInvocationHandler() {
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//proxy:生成的代理对象
//method:main方法中的实例对象service调用的方法,业务方法,可以获得业务方法的方法名
//args:业务方法的参数,是一个数组,里边保存传过来的参数
String mName = method.getName();
if("doSome".equals(mName)){
System.out.println("输出打印日志功能:"+ new Date());
//真正执行的是ServiceImpl中的方法,target是ServiceImpl实例对象,也就是需要执行的目标对象,
// 可以对args的参数进行更改
method.invoke(target,"张三",33);
method.invoke(target, args);
System.out.println("invoke方法执行完毕。");
}else {
System.out.println("其他方法的执行");
method.invoke(target,args);
System.out.println("其他方法执行结束需要执行的代码");
}
return null;
}
}
测试方法,主方法
public class Test {
public static void main(String[] args) {
//建立目标对象target
Service target = new ServiceImpl();
//将目标对象传入代理类中,代理类就可以对目标对象进行操作
MyInvocationHandler handler = new MyInvocationHandler(target);
//这里必须使用接口
Service service = (Service) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler);
//实际执行的是MyInvocationHandler中的invoke方法,并且将方法名和形参分别作为字符串和Object[]数组传过去,用method和args接收
//在invoke方法中接收
service.doSome("李四",12);
service.doOther();
}
}
输出:
输出打印日志功能:Mon Apr 20 18:52:22 CST 2020
doSome()方法执行张三 33
doSome()方法执行李四 12
invoke方法执行完毕。
其他方法的执行
doOther()方法执行
其他方法执行结束需要执行的代码

689

被折叠的 条评论
为什么被折叠?



