代理模式的核心作用是,控制对对象的访问,可以详细控制访问某个对象的方法,在调用这个方法前做前置处理,调用这个方法后做后置处理。这也是Spring中AOP(面向切面编程)的核心机制。
代理模式分为静态代理以及动态代理:
静态代理【static proxy】:
在静态代理中,代理对象与被代理对象必须实现同一个接口,完整保留被代理对象的接口样式,并且一直保持接口不变原则。代码实现:
实现的同一个接口【实际上就是被代理对象的所有操作】
package proxy.staticproxy;
/**
* 一个明星的相关操作
* @author acer
*/
public interface Star {
//签协议
void confer();
//签合同
void signContract();
//订票
void bookTicket();
//唱歌
void sing();
//收钱
void collectMoney();
}
实际类:
package proxy.staticproxy;
/**
* 真实的明星,实现了这个接口
* @author acer
*/
public class RealStar implements Star{
@Override
public void confer() {
System.out.println("RealStar.confer()");
}
@Override
public void signContract() {
System.out.println("RealStar.signContract()");
}
@Override
public void bookTicket() {
System.out.println("RealStar.bookTicket()");
}
@Override
public void sing() {
System.out.println("歌手唱歌");
}
@Override
public void collectMoney() {
System.out.println("RealStar.collectMoney()");
}
}
代理类:
package proxy.staticproxy;
/**
* 代理类,实现Star接口,代理类必须持有被代理类的对象
* @author acer
*/
public class ProxyStar implements Star{
private Star star;
public ProxyStar(Star star) {
super();
this.star = star;
}
@Override
public void confer() {
System.out.println("RealStar.confer()");
}
@Override
public void signContract() {
// TODO Auto-generated method stub
System.out.println("RealStar.signContract()");
}
@Override
public void bookTicket() {
// TODO Auto-generated method stub
System.out.println("RealStar.bookTicket()");
}
/**
* 唱歌的方法必须由被代理类自己实现
*/
@Override
public void sing() {
star.sing();
}
@Override
public void collectMoney() {
// TODO Auto-generated method stub
System.out.println("RealStar.collectMoney()");
}
}
测试:
package proxy.staticproxy;
public class Client {
public static void main(String[] args) {
Star real = new RealStar();
Star proxy = new ProxyStar(real);
proxy.confer();
proxy.collectMoney();
proxy.bookTicket();
proxy.signContract();
proxy.sing();
}
}
动态代理【dynamic proxy】:实际上就是动态生成代理类
相比于静态代理的优点:
JDK自带的动态代理:
——java.lang.reflect.Proxy :作用是动态生成代理类和对象
——java.lang.reflect.InvocationHandler(处理器接口)
可以通过invoke方法实现对真实角色的代理访问
每次通过Proxy生成代理类对象时,都要指定对应的对象处理器。
下面通过代码来实现以下jdk自带的动态代理:
首先接口以及被代理类是相同的
代理类:
package proxy.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 动态的代理类必须实现处理器接口
* @author acer
*/
public class StarHandler implements InvocationHandler{
private Star realStar;
public StarHandler(Star realStar) {
super();
this.realStar = realStar;
}
/**
* 通过这个方法实现对真实角色的代理访问
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("sing")){
method.invoke(realStar,args);
}
return null;
}
}
代理类必须实现InvocationHandler接口
测试以下:
package proxy.dynamicproxy;
import java.lang.reflect.Proxy;
public class Client {
public static void main(String[] args) {
Star realstar = new RealStar();
StarHandler handler = new StarHandler(realstar);
/**
* 通过Proxy类的newProxyInstance()方法动态的创建代理类
*/
Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class}, handler);
proxy.bookTicket();
proxy.sing();
}
}
这样就是实现了动态代理,具体动态代理的原理是怎样的呢??博主在下一篇进行简单的分析。