Java与形式之代理(Proxy)模式
Java与模式之代理(Proxy)模式
代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制原对象的引用。
代理模式的示意性实现类图如下
- 抽象主题角色:声明了真实主题与代理主题的共同接口,这样在可以使用真实主题的地方都可以使用代理主题。
- 代理主题角色:包含了一个对真实主题角色的引用,从而可以在任何时候操作真实主题角色。
代理模式的时序图如下
代理模式是怎样工作的:
- 代理主题并不改变主题的接口,因为模式的用意是不让客户端感觉到代理的存在。
- 代理使用委派将客户端的调用传递给真实主题对象,代理起的到是一个传递请求的作用。
- 代理主题在传递调用之前和之后都可以执行特定的操作,而不是单纯的传递请求。
JDK动态代理
jdk的动态代理是基于接口的,必须实现了某一个或多个任意接口才可以被代理,并且只有这些接口中的方法会被代理。
在Dao类的方法调用前输出xxx方法 start
public interface UserDao { public void save(); public void delete(); }
public class UserDaoImpl implements UserDao { @Override public void delete() { // TODO Auto-generated method stub System.out.println("deleted"); } @Override public void save() { // TODO Auto-generated method stub System.out.println("save"); } }
public class DaoProxy implements InvocationHandler { private Object target; public Object getTarget() { return target; } public void setTarget(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName()+" start!"); method.invoke(target,args); return null; } }
public static void main(String[] args) { UserDao uDao = new UserDaoImpl(); DaoProxy log = new DaoProxy(); log.setTarget(uDao); UserDao uDaoProxy = (UserDao)Proxy.newProxyInstance(uDao.getClass().getClassLoader(), uDao.getClass().getInterfaces(), log); uDaoProxy.delete(); uDaoProxy.save(); }
运行结果
delete start!
deleted
save start!
save
deleted
save start!
save
CGlib
- cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
- cglib封装了asm,可以在运行期动态生成新的class。
- cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。
Spring中AOP是基于代理的思想来实现,其代理就是基于CGlib来实现的。
参考:《Java与模式》