营销型网站建设大千建站,wordpress文章怎么备份,河北建设工程信息网网,网站制作建设兴田德java动态代理 JAVA的动态代理 代理模式 代理模式是常用的java设计模式#xff0c;他的特征是代理类与委托类有同样的接口#xff0c;代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类#xff0c;以及事后处理消息等。代理类与委托类之间通常会存在关联关系他的特征是代理类与委托类有同样的接口代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类以及事后处理消息等。代理类与委托类之间通常会存在关联关系一个代理类的对象与一个委托类的对象关联代理类的对象本身并不真正实现服务而是通过调用委托类的对象的相关方法来提供特定的服务。 按照代理的创建时期代理类可以分为两种。 静态代理由程序员创建或特定工具自动生成源代码再对其编译。在程序运行前代理类的.class文件就已经存在了。 动态代理在程序运行时运用反射机制动态创建而成。 首先看一下静态代理 1、Count.java Java代码 package net.battier.dao; /** * 定义一个账户接口 * * author Administrator * */ public interface Count { // 查看账户方法 public void queryCount(); // 修改账户方法 public void updateCount(); } 2、CountImpl.java Java代码 package net.battier.dao.impl; import net.battier.dao.Count; /** * 委托类(包含业务逻辑) * * author Administrator * */ public class CountImpl implements Count { Override public void queryCount() { System.out.println(查看账户方法...); } Override public void updateCount() { System.out.println(修改账户方法...); } } 、CountProxy.java package net.battier.dao.impl; import net.battier.dao.Count; /** * 这是一个代理类增强CountImpl实现类 * * author Administrator * */ public class CountProxy implements Count { private CountImpl countImpl; /** * 覆盖默认构造器 * * param countImpl */ public CountProxy(CountImpl countImpl) { this.countImpl countImpl; } Override public void queryCount() { System.out.println(事务处理之前); // 调用委托类的方法; countImpl.queryCount(); System.out.println(事务处理之后); } Override public void updateCount() { System.out.println(事务处理之前); // 调用委托类的方法; countImpl.updateCount(); System.out.println(事务处理之后); } } 3、TestCount.java Java代码 package net.battier.test; import net.battier.dao.impl.CountImpl; import net.battier.dao.impl.CountProxy; /** *测试Count类 * * author Administrator * */ public class TestCount { public static void main(String[] args) { CountImpl countImpl new CountImpl(); CountProxy countProxy new CountProxy(countImpl); countProxy.updateCount(); countProxy.queryCount(); } } 观察代码可以发现每一个代理类只能为一个接口服务这样一来程序开发中必然会产生过多的代理而且所有的代理操作除了调用的方法不一样之外其他的操作都一样则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能那么此时就必须使用动态代理完成。 再来看一下动态代理 JDK动态代理中包含一个类和一个接口 InvocationHandler接口 public interface InvocationHandler { public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; } 参数说明 Object proxy指被代理的对象。 Method method要调用的方法 Object[] args方法调用时所需要的参数 可以将InvocationHandler接口的子类想象成一个代理的最终操作类替换掉ProxySubject。 Proxy类 Proxy类是专门完成代理的操作类可以通过此类为一个或多个接口动态地生成实现类此类提供了如下的操作方法 public static Object newProxyInstance(ClassLoader loader, Class?[] interfaces, InvocationHandler h) throws IllegalArgumentException 参数说明 ClassLoader loader类加载器 Class?[] interfaces得到全部的接口 InvocationHandler h得到InvocationHandler接口的子类实例 Ps:类加载器 在Proxy类中的newProxyInstance方法中需要一个ClassLoader类的实例ClassLoader实际上对应的是类加载器在Java中主要有一下三种类加载器; Booststrap ClassLoader此加载器采用C编写一般开发中是看不到的 Extendsion ClassLoader用来进行扩展类的加载一般对应的是jre\lib\ext目录中的类; AppClassLoader(默认)加载classpath指定的类是最常使用的是一种加载器。 动态代理 与静态代理类对照的是动态代理类动态代理类的字节码在程序运行时由Java反射机制动态生成无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作而且提高了软件系统的可扩展性因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。 动态代理示例: 1、BookFacade.java Java代码 package net.battier.dao; public interface BookFacade { public void addBook(); } 2、BookFacadeImpl.java Java代码 package net.battier.dao.impl; import net.battier.dao.BookFacade; public class BookFacadeImpl implements BookFacade { Override public void addBook() { System.out.println(增加图书方法。。。); } } 、BookFacadeProxy.java package net.battier.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * JDK动态代理代理类 * * author student * */ public class BookFacadeProxy implements InvocationHandler { private Object target; /** * 绑定委托对象并返回一个代理类 * param target * return */ public Object bind(Object target) { this.target target; //取得代理对象 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); //要绑定接口(这是一个缺陷cglib弥补了这一缺陷) } Override /** * 调用方法 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object resultnull; System.out.println(事物开始); //执行方法 resultmethod.invoke(target, args); System.out.println(事物结束); return result; } } 3、TestProxy.java Java代码 package net.battier.test; import net.battier.dao.BookFacade; import net.battier.dao.impl.BookFacadeImpl; import net.battier.proxy.BookFacadeProxy; public class TestProxy { public static void main(String[] args) { BookFacadeProxy proxy new BookFacadeProxy(); BookFacade bookProxy (BookFacade) proxy.bind(new BookFacadeImpl()); bookProxy.addBook(); } } 但是JDK的动态代理依靠接口实现如果有些类并没有实现接口则不能使用JDK代理这就要使用cglib动态代理了。 Cglib动态代理 JDK的动态代理机制只能代理实现了接口的类而不能实现接口的类就不能实现JDK的动态代理cglib是针对类来实现代理的他的原理是对指定的目标类生成一个子类并覆盖其中方法实现增强但因为采用的是继承所以不能对final修饰的类进行代理。 示例 1、BookFacadeCglib.java Java代码 package net.battier.dao; public interface BookFacade { public void addBook(); } 2、BookCadeImpl1.java Java代码 package net.battier.dao.impl; /** * 这个是没有实现接口的实现类 * * author student * */ public class BookFacadeImpl1 { public void addBook() { System.out.println(增加图书的普通方法...); } } 3、BookFacadeProxy.java Java代码 package net.battier.proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 使用cglib动态代理 * * author student * */ public class BookFacadeCglib implements MethodInterceptor { private Object target; /** * 创建代理对象 * * param target * return */ public Object getInstance(Object target) { this.target target; Enhancer enhancer new Enhancer(); enhancer.setSuperclass(this.target.getClass()); // 回调方法 enhancer.setCallback(this); // 创建代理对象 return enhancer.create(); } Override // 回调方法 public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(事物开始); proxy.invokeSuper(obj, args); System.out.println(事物结束); return null; } } 4、TestCglib.java Java代码 package net.battier.test; import net.battier.dao.impl.BookFacadeImpl1; import net.battier.proxy.BookFacadeCglib; public class TestCglib { public static void main(String[] args) { BookFacadeCglib cglibnew BookFacadeCglib(); BookFacadeImpl1 bookCglib(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1()); bookCglib.addBook(); } } 转载于:https://www.cnblogs.com/richelle009/archive/2011/08/15/2139457.html