1.代理模式
代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
代理模式一般涉及到的角色有:
抽象角色 :声明真实对象和代理对象的共同接口;
代理角色 :代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
真实角色 :代理角色所代表的真实对象,是我们最终要引用的对象。
代理模式使用原因和应用方面
(1)授权机制 不同级别的用户对同一对象拥有不同的访问权利,如Jive论坛系统中,就使用Proxy进行授权机制控制,访问论坛有两种人:注册用户和游客(未注册用户),Jive中就通过类似ForumProxy这样的代理来控制这两种用户对论坛的访问权限.
(2)某个客户端不能直接操作到某个对象,但又必须和那个对象有所互动.
举例两个具体情况:
如果那个对象是一个是很大的图片,需要花费很长时间才能显示出来,那么当这个图片包含在文档中时,使用编辑器或浏览器打开这个文档,打开文档必须很迅速,不能等待大图片处理完成,这时需要做个图片Proxy来代替真正的图片.
如果那个对象在Internet的某个远端服务器上,直接操作这个对象因为网络速度原因可能比较慢,那我们可以先用Proxy来代替那个对象.
总之原则是,对于开销很大的对象,只有在使用它时才创建,这个原则可以为我们节省很多宝贵的Java内存. 所以,有些人认为Java耗费资源内存,我以为这和程序编制思路也有一定的关系.
(3)现实中,Proxy应用范围很广,现在流行的分布计算方式RMI和Corba等都是Proxy模式的应用
创建:1、需要一个具有集体需要代理方法的接口
2、一个实现该接口的具体类
3、一个实现InvocationHandler接口的代理类(需要附加的控制,权限控制,日志写入,事务控制等。。。)
4、一个整合具体方法类和代理的类
5、具体调用
完整实例:
事务写入
1、功能呢接口
package com.gxa.interfaces;
import com.gxa.entity.Admin;
import com.gxa.exception.AccountForbiddenException;
import com.gxa.exception.AccountNotExistException;
import com.gxa.exception.PasseordNotLegalException;
import com.gxa.exception.PasswordTnsertException;
import com.gxa.exception.ServiceException;
public interface AdminServiceInterface {
/**
* 登陆方法
*/
public Admin login(String account, String password)
throws ServiceException, PasseordNotLegalException,
AccountNotExistException, AccountForbiddenException,
PasswordTnsertException;
/**
* 冻结用户
*/
public void setAdminStatus(String account) throws ServiceException;
/**
* 解除用户冻结状态
*/
public void removeForbidden(String account) throws ServiceException;
/**
* 更新用户登陆时间
*/
public void updateLastLoginTime(Admin admin) throws ServiceException;
/**
* 修改密码
*/
public void changPassword(Admin admin, String newPassword) throws ServiceException;
}
2、具体实现接口的方法类
package com.gxa.service;
import com.gxa.entity.Admin;
import com.gxa.exception.AccountForbiddenException;
import com.gxa.exception.AccountNotExistException;
import com.gxa.exception.PasseordNotLegalException;
import com.gxa.exception.PasswordTnsertException;
import com.gxa.exception.ServiceException;
import com.gxa.interfaces.AdminServiceInterface;
public class AdminService1 implements AdminServiceInterface{
@Override
public void changPassword(Admin admin, String newPassword)
throws ServiceException {
// TODO Auto-generated method stub
}
@Override
public Admin login(String account, String password)
throws ServiceException, PasseordNotLegalException,
AccountNotExistException, AccountForbiddenException,
PasswordTnsertException {
// TODO Auto-generated method stub
return null;
}
@Override
public void removeForbidden(String account) throws ServiceException {
// TODO Auto-generated method stub
}
@Override
public void setAdminStatus(String account) throws ServiceException {
// TODO Auto-generated method stub
}
@Override
public void updateLastLoginTime(Admin admin) throws ServiceException {
// TODO Auto-generated method stub
}
}
3、日志代理类
package com.gxa.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import org.apache.log4j.Logger;
/**
* 日志代理
*
* @version 1.0 2012-8-11
* @author chenyq
*/
public class LogProxy<T> implements InvocationHandler {
private T t;
public static Logger logger = Logger.getLogger(LogProxy.class);
public LogProxy(T t) {
this.t = t;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//Teacher 方法
try {
method.invoke(t, args);
Class<?> clazz=t.getClass();
StringBuffer sb=new StringBuffer();
for(Object arg:args){
sb.append(arg);
}
String type=clazz.getSimpleName();
String method1=method.getName();
logger.debug(type+" Method: "+method1+" INFO: "+sb.toString());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
4、整合代理和Service服务
package com.gxa.proxyservice;
import java.lang.reflect.Proxy;
import com.gxa.proxy.LogProxy;
/**
* 代理LogService
* @param <I>
*/
public class LogService<T, I> {
public T t;//目标类
public LogProxy<T> log;// 代理日志类
public I iproxy=null;
//获得方法Service接口
public String getInterface(Class<T> clazz){
return clazz.getSimpleName();
}
@SuppressWarnings("unchecked")
public LogService(T t,LogProxy<T> log){
this.t=t;
this.log=log;
iproxy= (I)Proxy.newProxyInstance(t
.getClass().getClassLoader(), t.getClass().getInterfaces(),
log);
}
public I getIproxy(){
return iproxy;
}
}
5、具体调用
package com.gxa.test;
import com.gxa.exception.AccountForbiddenException;
import com.gxa.exception.AccountNotExistException;
import com.gxa.exception.PasseordNotLegalException;
import com.gxa.exception.PasswordTnsertException;
import com.gxa.exception.ServiceException;
import com.gxa.interfaces.AdminServiceInterface;
import com.gxa.proxy.LogProxy;
import com.gxa.proxyservice.LogService;
import com.gxa.service.AdminService;
public class AdminServiceProxyText {
/**
* @param args
*/
public static void main(String[] args) {
testAdminService();
}
/**
* 测试AdminService
*/
public static void testAdminService(){
//目标Service
AdminService as=new AdminService();
//代理Service
LogProxy<AdminService> log=new LogProxy<AdminService>(as);
//获得代理Service
LogService<AdminService,AdminServiceInterface> logs=new
LogService<AdminService, AdminServiceInterface>(as, log);
//测试登陆
try {
AdminServiceInterface adminservice=
logs.getIproxy();
adminservice.login("stu_chen", "121989092qq");
} catch (ServiceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PasseordNotLegalException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AccountNotExistException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AccountForbiddenException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (PasswordTnsertException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}