代理模式
代理模式最大的特点就是代理类和实际业务类实现同一个接口(或继承同一父类),代理对象持有一个实际对象的引用,外部调用时操作的是代理对象,而在代理对象的内部实现中又会去调用实际对象的操作
Java动态代理其实内部也是通过Java反射机制来实现的,即已知的一个对象,然后在运行时动态调用其方法,这样在调用前后作一些相应的处理。
普通业务接口
package com.pratise.study.proxy;
public interface Subject
{
public void hello(String str);
}
业务接口实现类
package com.pratise.study.proxy;
public class RealSubject implements Subject
{
@Override
public void hello(String str)
{
System.out.println("hello: " + str);
}
}
代理类(中介类)
package com.pratise.study.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @author cpgroup_lxw
* @version V1.0
* @Title: StudyProxy
* @Package com.pratise.study.proxy
* @Description: 动态代理对象
* @date 2019-2-12 16:06
*/
public class StudyProxy implements InvocationHandler {
private Object subject;
public StudyProxy(Object subject) {
this.subject = subject;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理开始");
method.invoke(subject,args);
System.out.println("代理结束");
return null;
}
}
实现类(调用)
package proxy;
import com.pratise.study.proxy.RealSubject;
import com.pratise.study.proxy.StudyProxy;
import com.pratise.study.proxy.Subject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @author cpgroup_lxw
* @version V1.0
* @Title: StudyProxyTest
* @Package proxy
* @Description: 调用动态代理对象
* @date 2019-2-12 16:14
*/
public class StudyProxyTest {
public static void main(String[] args) {
// 我们要代理的真实对象
RealSubject realSubject = new RealSubject();
InvocationHandler handler = new StudyProxy(realSubject);
System.out.println(handler.getClass());
/*
* 通过Proxy的newProxyInstance方法来创建我们的代理对象,我们来看看其三个参数
* 第一个参数 handler.getClass().getClassLoader() ,我们这里使用handler这个类的ClassLoader对象来加载我们的代理对象
* 第二个参数realSubject.getClass().getInterfaces(),我们这里为代理对象提供的接口是真实对象所实行的接口,表示我要代理的是该真实对象,这样我就能调用这组接口中的方法了
* 第三个参数handler, 我们这里将这个代理对象关联到了上方的 InvocationHandler 这个对象上
*/
Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler);
System.out.println(subject.getClass().getName());
subject.hello("world");
}
}