java动态代理
来源:互联网 发布:高音 知乎 编辑:程序博客网 时间:2024/06/05 15:05
1、代理模式:代理模式(Proxy Pattern)为其他对象提供一种代理以控制对这个对象的访问。代理对象起到中介作用,可去掉功能服务或增加额外的服务。
2、静态代理的两种实现方式:
(1)继承法:直接继承被代理类,实现其原有方法,并添加一些额外功能。
(2)聚合法:代理类实现被代理类相同功能的接口,并声明一个被代理对象的成员变量。
无论采用哪种方法,静态代理的代理类需要运行前开发完毕,而动态代理的代理类是运行时生成的。
3、动态代理的两种实现
(1)jdk的proxy:被代理类必须实现某个接口。
(2)CGLIB:第三方提供的,底层实现是ASM,直接更改类的字节码实现动态代理,对被代理类无特殊要求。
4、jdk中的动态代理——proxy
通过一个简单的例子说明
接口UserDao
public interface UserDao {public void add(String name);public void delete(String name);public void update(String name,int age);public List<String> search(int age);}
被代理类UserDaoImpl
public class UserDaoImpl implements UserDao {public void add(String name) {System.out.println("新增用户"+name);}public void delete(String name) {System.out.println("删除用户"+name);}public void update(String name, int age) {System.out.println("修改用户"+name+"的年龄为"+age);}public List<String> search(int age) {List<String> users=new ArrayList<String>();users.add("小红");users.add("小绿");users.add("小蓝");System.out.println("查询年龄为"+age+"的用户名字,查询结果列表为:"+users);return users;}}
public class TransactionInvocationHandler implements InvocationHandler{ //被代理对象private Object target;public TransactionInvocationHandler(Object target) {super();this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//调用被代理对象方法之前执行的操作 System.out.println("事务开启"); //通过反射机制,调用被代理对象方法Object result=method.invoke(target, args); //调用被代理对象方法之后执行的操作System.out.println("事务提交");return result;}}
调用Proxy的静态方法生成代理对象,并调用代理对象的相关方法
//被代理对象,最终要调用的UserDao userDao=new UserDaoImpl();//生成代理对象UserDao proxy=(UserDao) Proxy.newProxyInstance(userDao.getClass().getClassLoader(), userDao.getClass().getInterfaces(), new TransactionInvocationHandler(userDao));//调用代理对象的方法 proxy.add("小红");proxy.delete("小红");proxy.update("小红", 18);proxy.search(18);
运行结果
事务开启
新增用户小红
事务提交
事务开启
删除用户小红
事务提交
事务开启
修改用户小红的年龄为18
事务提交
事务开启
查询年龄为18的用户名字,查询结果列表为:[小红, 小绿, 小蓝]
事务提交
Class cls=proxy.getClass();System.out.println(cls.toGenericString());byte[] buffer=ProxyGenerator.generateProxyClass("$Proxy0", userDao.getClass().getInterfaces());OutputStream out=new FileOutputStream(new File("E:\\$Proxy0.class"));out.write(buffer);out.flush();out.close();
反编译以后的源码是:
public final class $Proxy0 extends Proxy implements UserDao{ private static Method m1; private static Method m2; private static Method m3; private static Method m5; private static Method m6; private static Method m0; private static Method m4; public $Proxy0(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); } public final boolean equals(Object paramObject) throws { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final String toString() throws { try { return (String)this.h.invoke(this, m2, null); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void add(String paramString) throws { try { this.h.invoke(this, m3, new Object[] { paramString }); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void delete(String paramString) throws { try { this.h.invoke(this, m5, new Object[] { paramString }); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final List search(int paramInt) throws { try { return (List)this.h.invoke(this, m6, new Object[] { Integer.valueOf(paramInt) }); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final int hashCode() throws { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } public final void update(String paramString, int paramInt) throws { try { this.h.invoke(this, m4, new Object[] { paramString, Integer.valueOf(paramInt) }); return; } catch (Error|RuntimeException localError) { throw localError; } catch (Throwable localThrowable) { throw new UndeclaredThrowableException(localThrowable); } } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m3 = Class.forName("proxy.UserDao").getMethod("add", new Class[] { Class.forName("java.lang.String") }); m5 = Class.forName("proxy.UserDao").getMethod("delete", new Class[] { Class.forName("java.lang.String") }); m6 = Class.forName("proxy.UserDao").getMethod("search", new Class[] { Integer.TYPE }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); m4 = Class.forName("proxy.UserDao").getMethod("update", new Class[] { Class.forName("java.lang.String"), Integer.TYPE }); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } }}
可以看到,调用代理类的add方法,最终调用了父类Proxy成员InvocationHandler的invoke方法,并且把add方法所对应的Method对象以及用户传递的参数、代理对象本身作为参数传递给invoke方法。
newProxyInstance源码,可以看到,其中最核心的就是Class<?> cl = getProxyClass0(loader, intfs); 生成了一个代表代理类的字节码对象,接下来就可以用反射的方式生成代理对象了,cons.newInstance(new Object[]{h});这行代码其实是调用了父类Proxy的构造方法生成一个代理对象,该构造方法将我们传递的InvocationHandler对象赋值给Proxy的成员变量h。getProxyClass0(loader, intfs)底层调用sun.misc.ProxyGenerator.generateProxyClass(String,Class<?>[])。
@CallerSensitive public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { Objects.requireNonNull(h); final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. */ Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { cons.setAccessible(true); return null; } }); } return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString(), e); } }
- Java 代理,动态代理
- [Java] Java 动态代理
- java代理及动态代理
- java代理模式--动态代理
- Java静态代理、动态代理
- Java 代理之 动态代理
- Java 代理与动态代理
- java静态代理,动态代理
- 代理模式&java动态代理
- Java代理与动态代理
- Java静态代理动态代理
- JAVA代理模式--动态代理
- java 代理和动态代理
- JAVA动态代理 代理模式
- Java动态代理--jdk代理
- Java动态代理--cglib代理
- Java 代理与动态代理
- java代理模式-动态代理
- 队内训练赛一
- LeetCode : Factorial Trailing Zeroes
- java基础----算法
- 如何把vim中的内容粘贴到外部
- Unity开发笔记整理
- java动态代理
- Log4j配置详解
- 链表求和
- 彻底搞定Android开发中软键盘的常见问题
- 微信小程序开发:提高应用速度小技巧
- 「这个控件叫什么」系列之加载占位图+页面指示器
- 递推递归练习P二分查找
- JAVA字符串的替换
- Android Notification通知