设计模式之《结构型模式》版块(基于Java) (16)

设计模式之《结构型模式》版块(基于Java)

代码示例 //目标对象的抽象层,接口父类 public interface ITeacherDao { /**授课方法*/ void teach(); void sayHello(String name); } //目标对象/被代理对象 public class TeacherDao implements ITeacherDao { @Override public void teach() { System.out.println("老师授课中..."); } @Override public void sayHello(String name) { System.out.println("Hello " + name); } } //----------------------------------------------------------------------------- //代理对象 public class ProxyFactory { /**维护一个目标对象 Object*/ private Object target; public ProxyFactory(Object target) { this.target = target; } /**给目标对象生成一个代理对象*/ public Object getProxyInstance(){ /* public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 1.ClassLoader:指定当前目标对象使用的类加载器 2.Class<?>[] interfaces:目标对象实现的接口类型集合,使用泛型方法确认类型 3.InvocationHandler:事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入 */ return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { /** * * @param proxy proxy是真实对象(目标对象)的真实代理对象,invoke方法可以返回调用代理对象方法的返回结果, 也可以返回对象的真实代理对象(com.sun.proxy.$Proxy0) * @param method 是调用的方法,可以用来方法过滤,得到方法的声明类等等。 * @param args 仅仅是被调用方法的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(proxy.getClass()); System.out.println("JDK代理开始..."); Object result = method.invoke(target, args); System.out.println("JDK代理结束..."); return result; } }); } } //----------------------------------------------------------------------------- //测试 public class Client { public static void main(String[] args) { //创建目标对象 TeacherDao teacherDao = new TeacherDao(); //给目标对象创建代理对象 ITeacherDao proxyTeacherDao = (ITeacherDao)new ProxyFactory(teacherDao).getProxyInstance(); //class com.sun.proxy.$Proxy0 内存中动态生成了代理对象 // System.out.println(proxyTeacherDao.getClass()); //通过代理对象调用方法 //proxyTeacherDao.teach(); proxyTeacherDao.sayHello("tom"); } } Cglib代理 Cglib代理模式的基本介绍

静态代理和JDK代理模式都要求目标对象是实现一个接口,但是有时候目标对象只 是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现 代理-这就是Cglib代理

Cglib代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功 能扩展, 有些书也将Cglib代理归属到动态代理。

Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接 口.它广泛的被许多AOP的框架使用,例如Spring AOP,实现方法拦截

在AOP编程中如何选择代理模式:

目标对象需要实现接口,用JDK代理

目标对象不需要实现接口,用Cglib代理

Cglib包的底层是通过使用字节码处理框架ASM来转换字节码并生成新的类

Cglib代理模式实现步骤 + 注意事项

需要引入cglib的jar文件

在内存中动态构建子类,注意代理的类不能为final,否则报错 java.lang.IllegalArgumentException:

目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的 业务方法.

应用实例

完成静态代理的应用案例

UML类图

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzzjxd.html