1. 定义:为其他对象提供一种代理以控制对这个对象的访问。Provide a surrogate or placeholder for another object to control access to it.
2. 简单示例代码
public interface DBOperation { //定义最高抽象的接口,此接口定义了对一个数据库表的一些操作。
public boolean add();
public boolean delete();
public boolean update();
public boolean select();
}
import java.sql.Connection;import java.sql.DriverManager;public class DBOProxy implements DBOperation{ //代理类 实现上述接口,但是具体的逻辑要由真实类实现。 //代理类可以使得高层调用不发生修改的情况下,可以修改被代理类的实现逻辑。private static Connection conn=null; //创建一个数据库的连接,此处并没有实际数据库连接。private DBOperation obj=null; //代理类中可以为真实类提供 共有的属性 比如一个数据库连接。public DBOProxy(){ //构造函数中从外部传入一个被代理对象,或者调用默认被代理对象 this(new DBOpimpl(conn)); }public DBOProxy(DBOperation dbo) {this.obj=dbo;}private static int count=0;public void Count() //代理类可以提供 自己所有的方法 用于统计真实类的调用情况等。{System.out.println("我已经代理处理"+count+"个方法了,累死了");}/* * public boolean add() {if(obj==null)obj=new DBOpimpl(conn); //实现延迟加载 在实际调用的时候才产生真实类return obj.add(); //这样在每个方法里面都需要增加判断代码} * */@Overridepublic boolean add() {// TODO Auto-generated method stubcount++;if(obj.add())return true;return false;}@Overridepublic boolean delete() {// TODO Auto-generated method stubcount++;if(obj.delete())return true;return false;}@Overridepublic boolean update() {// TODO Auto-generated method stubcount++;if(obj.update())return true;return false;}@Overridepublic boolean select() {// TODO Auto-generated method stubcount++;if (obj.select())return true;return false;}}public class DBOpimpl implements DBOperation { //真实类,可以实现特有的逻辑 private Connection conn=null; public DBOpimpl(Connection conn) { // TODO Auto-generated constructor stub this.conn=conn; } @Override public boolean add() { // TODO Auto-generated method stub System.out.println("增加成功"); return true; } @Override public boolean delete() { // TODO Auto-generated method stub System.out.println("删除成功"); return true; } @Override public boolean update() { // TODO Auto-generated method stub System.out.println("更新成功"); return true; } @Override public boolean select() { // TODO Auto-generated method stub System.out.println("查询成功"); return true; }}
System.out.println("************代理模式************"); DBOperation proxy=new DBOProxy(); proxy.add();************代理模式************增加成功3. 指定代理示例
public class Designateimpl implements DBOperation{ //由 真实类 指定能调用自己的代理,其他未指定的代理类都无法调用自己。
private Connection conn=null;
public Designateimpl(Connection conn) {
// TODO Auto-generated constructor stub
this.conn=conn;
}
private DBOProxy proxy=null;
public DBOProxy getProxy(){ //自己指定代理后 返回此代理的引用
this.proxy=new DBOProxy(this); //此处指定的代理 还是上面的代理
return this.proxy;
}
private boolean isProxy()
{
if (this.proxy==null)
return false;
else
return true;
}
@Override
public boolean add() {
// TODO Auto-generated method stub
if(isProxy()) //只有通过自己的代理 才能访问真实类的方法。
{
System.out.println("增加成功");
return true;
}
else
{
System.out.println("增加失败,请使用我的代理");
return false;
}
}
@Override
public boolean delete() {
// TODO Auto-generated method stub
if(isProxy())
{
System.out.println("删除成功");
return true;
}
else
{
System.out.println("删除失败,请使用我的代理");
return false;
}
}
@Override
public boolean update() {
// TODO Auto-generated method stub
if(isProxy())
{
System.out.println("更新成功");
return true;
}
else
{
System.out.println("更新失败,请使用我的代理");
return false;
}
}
@Override
public boolean select() {
// TODO Auto-generated method stub
if(isProxy())
{
System.out.println("查询成功");
return true;
}
else
{
System.out.println("查询失败,请使用我的代理");
return false;
}
}
}
DBOProxy proxy21=new DBOProxy(new Designateimpl(null)); DBOProxy proxy2=new Designateimpl(null).getProxy(); proxy21.delete();proxy21.Count(); proxy2.delete();proxy2.Count();//此处 前面调用了一次add()方法所以处理了2次。 从结果可知,由于前面一个未使用指定的代理所以调用失败,而后面一个使用了指定的代理 调用成功删除失败,请使用我的代理我已经代理处理2个方法了,累死了删除成功我已经代理处理3个方法了,累死了4. 动态代理示例
public class DynamicProxy implements InvocationHandler{
DBOperation obj=null; //
public DynamicProxy(DBOperation obj) {
// TODO Auto-generated constructor stub
this.obj=obj;
}
public DBOperation getProxy() //返回动态代理实例
{ //指定真实类加载器、调用的接口方法(注意真实类一定要继承自某个接口) 和实现了InvocationHandler接口的动态代理类。
return (DBOperation) Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
//此处返回的类型为接口类型,返回类类型时会产生ClassCast异常
}
//实现InvocationHandler接口的invoke方法,指定代理的实例将调用的方法和参数,并将结果返回。
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("动态代理发生调用,生人回避");
return method.invoke(this.obj, args); //通过委托调用指定类中的方法。
}
}
DBOperation dbo=new DBOpimpl(null); //动态代理绑定的真实类 DBOperation proxy3= new DynamicProxy(dbo).getProxy(); //获得动态代理实例 proxy3.select();proxy3.update(); //动态代理调用动态代理发生调用,生人回避查询成功动态代理发生调用,生人回避更新成功