发布时间:2025-12-10 19:35:37 浏览次数:18
设计模式:卑微的代理模式是什么_代理体系设计代理模式类图:代理模式的本质:提供了间接对目标对象进行访问的方式,即通过代理对象访问目标对象,这样做的好处是:可以在目标对象实现的功能上,增加额外的功能补充,即扩展目标对象的功能。…
代理模式类图:
代理模式的本质:
提供了间接对目标对象进行访问的方式,即通过代理对象访问目标对象,这样做的好处是:可以在目标对象实现的功能上,增加额外的功能补充,即扩展目标对象的功能。
具体实现(一句话描述):代理类和目标类同时实现同一个接口(目标接口),同时代理接口还有目标接口的引用(很好想:你请一个代理来帮你干某些事情,你是不是得告诉他你的基本信息)。
举个例子:周杰伦开演唱会!
代码表示:
目标接口:
public interface IStar { void sing();}希望我今天分享的这篇文章可以帮到您。
目标类:
public class JaySing implements IStar { @Override public void sing() { System.out.println("周杰伦在唱歌"); }}代理类:
public class JayProxy implements IStar{ private IStar iStar; /*默认代理自己*/ public JayProxy(){ this.iStar = new JayProxy(); } public JayProxy(JaySing iStar){ this.iStar =iStar; } @Override public void sing() { this.before(); iStar.sing(); this.after(); } public void before(){ //do sth. before method invoke } public void after(){ //do sth. after method invoke }}这样我们就完成了一个简单代理模式了,在没有改变目标类的情况下增强了目标方法的功能(本质)。
上面的代理模式被称为静态代理模式。
那么什么是动态代理?
动态代理的主要特点就是能够在程序运行时JVM才为被代理对象生成代理对象。
本质上还是一样的,只是他的代理的对象生成的时机不同。
动态代理分为:jdk动态代理和cglib动态代理。
再来看看的们的区别:jdk 动态代理基于接口i,cglib动态代理基于类!
jdk动态代理代码:
目标接口:
public interface IStar { void sing();}目标实现类:
public class JaySing implements IStar{ @Override public void sing() { System.out.println("周杰伦在唱歌!"); }}动态代理的精髓是不需要知道他要代理谁,比如我这个代理既可以代理周杰伦也可以代理周杰,想代理谁就代理谁,所以我们不能像静态代理那样明确指出他就代理某一个对象。所以我们需要一个中转站来鉴别我们具体需要代理的对象。
代理中转站:
public class ProxyFactory { public static Object getProxy(Object target) { MyProxyHandler handle = new MyProxyHandler(target); Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handle); return proxy; }}(这样理解可能会更好:可以把这ProxyFactory 比作一个代理公司,自然一个人是不足以代理所有的客户,他的职责就是为每一个需要被代理的对象分配一个代理。)
实际想对哪个方法进行增强:
public class MyProxyHandler implements InvocationHandler { /*the proxy object*/ private Object target; public MyProxyHandler(Object target){ this.target =target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); method.invoke(target, args); after(); return null; } private void before(){ //do sth. before the method invoke System.out.println("do sth. before the method invoke"); } private void after(){ //do sth. after the method invoke System.out.println("do sth. after the method invoke"); }}测试代码:
class Test { public static void main(String[] args) { IStar iStar = new JaySing(); IStar starProxy = (IStar) ProxyFactory.getProxy(iStar); starProxy.sing(); }}运行结果:
do sth. before the method invoke周杰伦在唱歌!do sth. after the method invokecglib 动态代理:
代码:
目标类:
public class JaySing { public void sing() { System.out.println("周杰伦在唱歌!"); }}增强类:
public class MyMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object target, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { before(); //这行代码需要好好理解一下 Object object = methodProxy.invokeSuper(target, args); after(); return object; } private void before() { //do sth. before the method invoke System.out.println("do sth. before the method invoke"); } private void after() { //do sth. after the method invoke System.out.println("do sth. after the method invoke"); }}测试类:
class Test { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); //设置目标类的字节码文件 enhancer.setSuperclass(JaySing.class); //设置回调函数 enhancer.setCallback(new MyMethodInterceptor()); JaySing jaySing = (JaySing) enhancer.create(); jaySing.sing(); }}测试结果:
do sth. before the method invoke周杰伦在唱歌!do sth. after the method invokeSpring中使用的是哪种代理呢?
如果一个类有顶层接口,则默认使用jdk的动态代理来代理,如果直接是一个类,则使用cglib动态代理。
总结下来就是:静态代理需要手动去写代理类,而动态代理则不需要,静态代理和jdk动态代理都是基于接口实现的代理,cglib基于类实现的,动态代理都需要一个代理中转站来处理相应的代理来实现最终对目标方法的增强。
动态代理的应用:Spring的AOP,加事务,加权限,加日志。