版权声明:未经本人同意,不得私自转载 https://blog.csdn.net/weixin_41866744/article/details/87897599
设计模式:前人总结的一套解决特定问题的代码
代理设计模式优点:1.保护真实对象 2.让真实对象职责更明确. 3.扩展
代理设计模式场景: 真实对象.(老总) 代理对象(秘书) 抽象对象(抽象功能),谈小目标
静态代理:由代理对象代理所有真实对象的功能.
1.自己编写代理类 2.每个代理的功能需要单独编写
package com.tao.pojo; /** * 静态代理主体类 * */ public class A implements StaticInf{ public void a(){ System.out.println("执行a方法的业务逻辑"); } /** * 假设现在老总又要做b方法 */ @Override public void b() { System.out.println("执行b方法的业务逻辑"); } }
package com.tao.pojo; /** * 代理类 */ public class B implements StaticInf{ private A a = new A(); @Override public void a() { System.out.println("执行方法前处理的业务逻辑"); a.a(); System.out.println("执行方法后处理的业务逻辑"); } /** * 代理类需要跟着代理此方法 */ @Override public void b() { System.out.println("执行方法前处理的业务逻辑"); a.b(); System.out.println("执行方法后处理的业务逻辑"); } }
package com.tao.pojo; /** * 静态代理接口 * */ public interface StaticInf { void a(); void b(); }
package com.tao.pojo; public class Test { public static void main(String[] args) { test1(); } /** * 静态代理测试 */ public static void test1(){ B b = new B(); b.a(); b.b(); } }
静态代理设计模式的缺点:当代理功能比较多时,代理类中方法需要写很多.
动态代理:为了解决静态代理频繁编写代理功能缺点.
分类:1. JDK 提供的 2. cglib 动态代理
JDK 动态代理
1.和 cglib 动态代理对比:
优点: jdk 自带,不需要额外导入 jar;
缺点: 真实对象必须实现接口;利用反射机制.效率不高.
package jdk_dynamic_proxy; public interface JdkDynamicInf { void a(); void b(); }
package jdk_dynamic_proxy; public class A implements JdkDynamicInf{ @Override public void a() { System.out.println("执行a方法的业务逻辑"); } @Override public void b() { System.out.println("执行b方法的业务逻辑"); } }
package jdk_dynamic_proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class B implements InvocationHandler{ private A a = new A(); @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("执行方法前的业务逻辑"); Object result = method.invoke(a, args); System.out.println("执行方法前的业务逻辑"); return result; } }
package jdk_dynamic_proxy; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { B b = new B(); //第一个参数:反射时使用的类加载器 //第二个参数:Proxy需要实现上面接口 //第三个参数:通过接口对象调用方法时,需要调用哪个类的invoke方法(你做了拓展功能的类) JdkDynamicInf jdkDynamicInf = (JdkDynamicInf) Proxy.newProxyInstance(A.class.getClassLoader(), new Class[]{JdkDynamicInf.class}, b); jdkDynamicInf.a(); jdkDynamicInf.b(); } }
cglib 动态代理:
cglib 优点:基于字节码,生成真实对象的子类;运行效率高于 JDK 动态代理;不需要实现接口
cglib 缺点:非 JDK 功能,需要额外导入 jar
package cglib_proxy; public class A { void a(){ System.out.println("执行a方法的业务逻辑"); } void b(){ System.out.println("执行b方法的业务逻辑"); } }
package cglib_proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class B implements MethodInterceptor{ /** * arg0 生成的子类对象 * arg1 代理的方法 * arg2 参数 * arg3 生成的代理方法 */ @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("执行方法前逻辑"); //invoke()调用子类重写的方法 // arg1.invoke(arg0, arg2); //父类代理对象 //invokeSuper Object result = arg3.invokeSuper(arg0, arg2); // 子类的方法 System.out.println("执行方法后逻辑"); return result; } }
package cglib_proxy; import net.sf.cglib.proxy.Enhancer; public interface Test { public static void main(String[] args) { Enhancer enhancer = new Enhancer(); //生成哪个类的子类 enhancer.setSuperclass(A.class); //设置重写的真实类 enhancer.setCallback(new B()); A a = (A) enhancer.create(); a.a(); a.b(); } }