Java代理技术
来源:互联网 发布:春运迁徙大数据图 编辑:程序博客网 时间:2024/05/22 12:37
public interface UserManager {public void save(String name,String pwd);public void update(String name,String pwd,String repwd);public void delete(int id);public String select(int id);}
public class UserManagerImpl implements UserManager{public void save(String name, String pwd) {System.out.println("UserManagerImpl ------save()");}public void update(String name, String pwd, String repwd) {System.out.println("UserManagerImpl ------save()");}public void delete(int id) {System.out.println("UserManagerImpl ------save()");}public String select(int id) {return "UserManagerImpl select";}}
public class UserManagerSPorxy implements UserManager {UserManager userManager;public UserManagerSPorxy(UserManager userManager){this.userManager = userManager;}public void save(String name, String pwd){log();userManager.save(name, pwd);}public void update(String name, String pwd, String repwd){log();userManager.update(name, pwd, repwd);}public void delete(int id) {log();userManager.delete(id);}public String select(int id) {log();return userManager.select(id);}public void log(){System.out.println("-------write log into logfile............");}}
public class TestStaticPorxy {public static void main(String[] args) {UserManager userManager = new UserManagerSPorxy(new UserManagerImpl());userManager.delete(3);userManager.save("aa", "bb");}}
结果:
参数说明:
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 接口提供了生成动态代理类的能力。
package net.battier.dao;public interface BookFacade {public void addBook();}
package net.battier.dao.impl;import net.battier.dao.BookFacade;public class BookFacadeImpl implements BookFacade {@Overridepublic void addBook() {System.out.println("增加图书方法。。。");}}BookFacadeProxy.javapackage 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 result=null;System.out.println("事物开始");//执行方法result=method.invoke(target, args);System.out.println("事物结束");return result;}}
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修饰的类进行代理。
示例
package net.battier.dao;public interface BookFacade {public void addBook();}
package net.battier.dao.impl;/** * 这个是没有实现接口的实现类 * * @author student * */public class BookFacadeImpl1 {public void addBook() {System.out.println("增加图书的普通方法...");}}
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;}}
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 cglib=new BookFacadeCglib();BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());bookCglib.addBook();}}
- JAVA中的代理技术
- java代理技术
- Java的代理技术
- Java代理技术
- java反射代理技术
- java动态代理技术
- Java代理技术
- java代理技术简介
- java技术-静态代理到动态代理
- 黑马程序员--Java代理技术
- Java中的动态代理技术
- java技术之静态代理
- 【黑马程序员】java中的--------------代理类与动态代理技术
- JAVA AOP编程之动态代理技术
- 黑马程序员——java代理技术
- java基础加强--动态代理技术
- java代理技术二(Cglib实现)
- 公共技术点之 Java 动态代理
- UniGui手动终止一个会话
- javascript 如何判断该月的共有多少天(不用判断是否是闰年);
- 程序员学习能力提升三要素
- 是否应该使用ARC?
- 在次线程中下载,在主线程更新的例子
- Java代理技术
- WIN7可中SQL SERVER 2008安装时出现不能在控件上调用 Invoke 或 BeginInvoke错误(终极解决方法)
- C++ 队列 实现 多项式 加减法
- ZOJ 2224 Investment
- Shell脚本调试技术
- Java 入门 三 (Java三大特性 之一 封装 )
- Fedora下自动挂载Windows分区的方法及权限问题
- nbu 2412 Dice
- FileStream 和 StreamWriter/StreamReader