代理模式作为设计模式的一种,在各大框架的功能底层发挥很重要的作用,比如Spring的AOP,其底层就是用到了动态代理的技术思想,其基本步骤如下:
- 创建接口:
package com.pojo;
public interface ShowInfo {
String showInfo();
}
- 创建类实现接口
package com.pojo;
public class User implements ShowInfo{
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String showInfo(){
System.out.println(name+age);
return name;
}
}
- 创建代理对象
final User user = new User();//创建被代理的真实对象
User proxyUser = (User) Proxy.newProxyInstance(//调用该方法生成代理对象
user.getClass().getClassLoader(),//传入某个真实对象的类加载器
user.getClass().getInterfaces(),//传入该真实类实现的接口数组
new InvocationHandler() {//实现该接口的匿名类
/**
*该方法会在代理对象调用真实对象的方法时被调用
* @param proxy
* @param method 封装代理对象调用真实对象的Method对象
* @param args 封装代理对象调用的方法中的参数数组
* @return 返回值为
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//必须用method对象调用invoke方法,并传入真实对象才能真正实现代理调用真实对象的过程
Object obj = method.invoke(user,args);//该方法的返回值实际上就是代理对象调用真实对象方法的返回值
System.out.println("调用invoke");
return obj;//将invoke方法(实际对象的某个被调用的方法)的返回值返回,在外部的表现为一个正常的代理现象
}
});
String name= proxyUser.showInfo();
System.out.println(name);
以上仅仅是创建了一个代理对象来替代某个真实对象实现某些方法,下面我们将介绍如何实现功能的增强
- 上面
invoke
方法中的args
参数是method
方法的参数数组,因此如果被代理对象调用的方法中有参数时,我们可以通过在invoke
方法体中编写代码逻辑来实现该对某方法的功能增强 method.getName()
可以用来判断被调用的方法名称,以此来区分不同方法的不同功能增强
动态代理的技术我们并不需要会写,但是需要懂其中的逻辑,这对后面框架学习的底层原理的理解帮助很大