代理模式为对象提供一种代理,以控制这个对象的访问。代理模式分为静态代理和动态代理。
一、静态代理
静态代理的实现,有一个接口和一个实现了这个接口的实体类,一般分别称之为抽象角色和真实角色。另有一个代理类,称之为代理角色,代理真实角色后,会做一些附属操作。
首先建立一个接口,留学StudyAbroad,然后建立一个实现这个接口的类,学生Student,然后建立一个代理Proxy,通过这个代理去代理学生,代理的时候,可以在原有类的基础上增加一些代理类才能做的操作。在测试类里面完成一些操作。
//留学的接口
public interface StudyAbroad {
void studyAbroad();
}
//学生要留学
public class Student implements StudyAbroad{
@Override
public void studyAbroad() {
System.out.println("学生要出过留学");
}
}
//通过组合的方式代理学生
public class Proxy implements StudyAbroad{
private Student student;
public Proxy() {}
public Proxy(Student student) {
this.student = student;
}
/**
* 帮助学生出过留学
*/
@Override
public void studyAbroad() {
student.studyAbroad();
fare();
}
public void fare() {
System.out.println("收取中介费");
}
}
//测试
public class Test {
public static void main(String[] args) {
Student student = new Student();
Proxy proxy = new Proxy(student);
proxy.studyAbroad();
}
}
静态代理中,一个实现类必须有一个对应的代理,随着代码量增大,代码会变得非常冗余。我们可以用动态代理解决这个问题。
二、动态代理
动态代理的代理类是动态生成的,而不是直接写好的。动态代理分为两大类,基于接口的动态代理(JDK动态代理)和基于类的动态代理(cglib动态代理)。JDK动态代理,主要是实现InvocationHandler接口并重写其中的invoke()方法,再通过Proxy的newProxyInstance方法获得代理类。
//用这个类自动生产代理类
public class ProxyInvocationHandler implements InvocationHandler {
//被代理的接口
private Object target;
public void setTarget(Object target) {
this.target = target;
}
//生成,得到代理类
public Object getProxy() {
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
//处理代理实例,并返回结果
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = method.invoke(target, args);
fare();
return result;
}
public void fare() {
System.out.println("交中介费");
}
}
public static void main(String[] args) {
//真实角色
Student student = new Student();
//代理角色
ProxyInvocationHandler handler = new ProxyInvocationHandler();
handler.setTarget(student);
StudyAbroad proxy = (StudyAbroad) handler.getProxy();
proxy.studyAbroad();
}