什么是代理
增强一个类的功能
目标对象
需要增强的对象
代理对象
增强或者修改之后的对象
静态代理
继承方式
实现方式
定义功能类
public class IndexDaoImpl{ public void doSomeThing(){ System.out.println("do some thing ..."); } public String doSomeThing(String str) { System.out.println("do some thing ..."+str); return str; } }
定义代理类 extend 目标功能类,重写需要增强的方法
//增加日志记录 public class IndexLogDaoImpl extends IndexDaoImpl{ @Override public void doSomeThing() { System.out.println("日志记录"); super.doSomeThing(); } } //增加权限管理 public class IndexPowerDaoImpl extends IndexDaoImpl{ @Override public void doSomeThing() { System.out.println("权限管理"); super.doSomeThing(); } } //增加性能监控 public class IndexTimeDaoImpl extends IndexDaoImpl{ @Override public void doSomeThing() { System.out.println("性能监控"); super.doSomeThing(); } }
测试
public class StaticExtendProxyTest { public static void main(String[] args) { IndexDaoImpl dao1 = new IndexLogDaoImpl(); IndexDaoImpl dao2 = new IndexPowerDaoImpl(); IndexDaoImpl dao3 = new IndexTimeDaoImpl(); dao1.doSomeThing(); dao2.doSomeThing(); dao3.doSomeThing(); } }
缺点
需要代理的类或者需要增强的功能过多时,会产生太多的代理类,产生类爆炸
聚合方式 :需要接口
实现方式
定义接口
public interface IndexDao { public void doSomeThing(); }
定义功能实现类
public class IndexDaoImpl implements IndexDao{ @Override public void doSomeThing(){ System.out.println("do some thing ..."); } }
定义代理类 implements 接口,内部维护目标对象
//增减日志记录 public class IndexLogDaoImpl implements IndexDao{ private IndexDao dao ; public IndexLogDaoImpl(IndexDao dao){ this.dao = dao; } @Override public void doSomeThing() { System.out.println("日志管理"); dao.doSomeThing(); } } //增加权限管理 public class IndexPowerDaoImpl implements IndexDao{ private IndexDao dao ; public IndexLogDaoImpl(IndexDao dao){ this.dao = dao; } @Override public void doSomeThing() { System.out.println("权限管理"); dao.doSomeThing(); } } //增减性能监控 public class IndexTimeDaoImpl implements IndexDao{ private IndexDao dao ; public IndexLogDaoImpl(IndexDao dao){ this.dao = dao; } @Override public void doSomeThing() { System.out.println("性能监控"); dao.doSomeThing(); } }
优点
可以根据需要增强的功能以及功能顺序进行自由组合,jdk动态代理的实现方式是依赖聚合完成的。
动态代理
由于静态代理的局限性,出现了动态代理
在运行期,动态给某一类目标对象进行功能增强产生代理类
动态代理的实现方式
gdk动态代理
回调接口实现代理逻辑
public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target){ this.target=target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("gdk 动态代理========="); return method.invoke(target,args); } }
GDK动态代理实现应用
IndexDao jdkProxy = (IndexDao) Proxy.newProxyInstance(DynamicProxyTest.class.getClassLoader(),//类加载器 new Class[]{IndexDao.class},//接口列表 new MyInvocationHandler(new IndexDaoImpl())//InvocationHandler接口回调实现 );
cglib动态代理
回调接口实现代理逻辑
public class CglibProxy implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("cglib 动态代理========="); return methodProxy.invokeSuper(o,objects); } }
cglib代理实现应用
Enhancer hancer = new Enhancer();//创建代理核心类对象 hancer.setSuperclass(IndexDaoImpl.class);//设置目标对象 hancer.setCallback(new CglibProxy());//设置接口回调实现对象 IndexDaoImpl cglibProxy = (IndexDaoImpl) hancer.create();//创建代理对象