Java-马士兵动态代理模式
Java-马士兵动态代理模式
模拟jdk的动态代理的实现原理, 这些东西没有必要写出来,写项目的时候一般用不上,主要是为了面试和理解原理;
java动态代理有什么作用
作用非常大,在很多底层框架中都会用得到,比如struts,Spring等都用到了动态代理,它的作用很简单,就是将你要使用的类,重新生成一个子类或本类,这样框架就可以利用这个新生成的类做一些事情,比如在该类的方法前后加一些代码。。
这样的话,你想像一下,你是不是不用修改任何已经编写好的代码,只要使用代理就可以灵活的加入任何东西,将来不喜欢了,不用也不会影响原来的代码。
https://www.zhihu.com/question/20794107/answer/23334315
代理模式-聚合与继承方式比较
参考地址:http://www.cnblogs.com/shamgod/p/4591782.html
一、概述
1.目标:要在Tank的move()方法做时间代理及日志代理(可以设想以后还要增加很多代理处理),且代理间的顺序可活更换
2.思路:
(1)聚合:代理类聚合了被代理类,且代理类及被代理类都实现了movable接口,则可实现灵活多变,具体看代码
(2)继承:继承不够灵活,具体看代码
 
 
二、代码
1.Movable.java
2.Tank.java
3.TankTimeProxy.java
4.TankLogProxy.java
5.Tank2Time.java
6.Tank3Log.java
7.Client.java
1.Movable.java
- public
interface Movable { - public
void move(); - }
 
 
 
2.Tank.java
- import java.util.Random;
 - public
class Tank implements Movable { - @Override
 - public
void move() { - System.out.println("Tank moving.......");
 - try {
 - Thread.sleep(new Random().nextInt(5000));
 - } catch (InterruptedException e) {
 - e.printStackTrace();
 - }
 - }
 - }
 
 
 
3.TankTimeProxy.java
- public
class TankTimeProxy implements Movable { - Movable m;
 - public TankTimeProxy(Movable m) {
 - this.m = m;
 - }
 - @Override
 - public
void move() { - System.out.println("Time Proxy start...........");
 - long start = System.currentTimeMillis();
 - m.move();
 - long end = System.currentTimeMillis();
 - System.out.println("花费时间:"+(end - start));
 - System.out.println("Time Proxy end...........");
 - }
 - }
 
4.TankLogProxy.java
- public
class TankLogProxy implements Movable { - Movable m;
 - public TankLogProxy(Movable m) {
 - this.m = m;
 - }
 - @Override
 - public
void move() { - System.out.println("Log Proxy start...........");
 - m.move();
 - System.out.println("Log Proxy end...........");
 - }
 - }
 
 
 
5.Tank2Time.java
- public
class Tank2Time extends Tank { - public
void move(){ - System.out.println("Tank2 time start...........");
 - long start = System.currentTimeMillis();
 - super.move();
 - long end = System.currentTimeMillis();
 - System.out.println("花费时间:"+(end - start));
 - System.out.println("Tank2 time end...........");
 - }
 - }
 
 
 
6.Tank3Log.java
- public
class Tank3Log extends Tank2Time { - public
void move(){ - System.out.println("Tank3Log start...........");
 - super.move();
 - System.out.println("Tank3Log end...........");
 - }
 - }
 
 
 
7.Client.java
- public
class Client { - @Test
 - public
void testProxy(){ - Tank t = new Tank();
 - Movable m;
 - //一、聚合的方式(较灵活,因为实现了接口)
 - //1.1聚合方式的代理,先日志代理,后时间代理
 - TankTimeProxy ttp1 = new TankTimeProxy(t);
 - TankLogProxy tlp1 = new TankLogProxy(ttp1);
 - m = tlp1;
 - m.move();
 - System.out.println("\n==============================分隔线==========================\n");
 - //1.2聚合方式的代理,先时间代理,后日志代理(可以灵活切换顺序)
 - TankLogProxy tlp2 = new TankLogProxy(t);
 - TankTimeProxy ttp2 = new TankTimeProxy(tlp2);
 - m = ttp2;
 - m.move();
 - System.out.println("\n==============================分隔线==========================\n");
 - //二、继承的方式
 - //2.1代理时间
 - Tank2Time t2 = new Tank2Time();
 - t2.move();
 - System.out.println("\n==============================分隔线==========================\n");
 - //2.2先代理日志,后时间,不能灵活切换
 - Tank3Log t3 = new Tank3Log();
 - t3.move();
 - }
 - }
 
 
 
三、运行结果

 
 
四、小结
凡是要求灵活多变的功能,多数用接口多态实现
三:问题引出
每实现一个需求都需要写一个代理类,比如:为了实现在方法前后加日志TankLogProxy、为了实现记录方法运行时间TankTimeProxy,随着系统的复杂,如果还需要实现权限、事务管理,用这种设计方法,代理类会越来越多。有没有一种方式,能够让我们不写这些代理类? 动态代理,动态的去代理,代理类是动态生成的,不需要我们编写,这样就可以解决这个代理类很多的问题,这样会极大地减少了我们的工作。
代理模式-动态代理 调用Proxy.newProxyInstance()
http://www.cnblogs.com/shamgod/p/4592014.html
一、概述
1.目标:不自己写代理类,利用Proxy.newProxyInstance()动态生成
2.用到的知识点:
(1)//编译源码,生成class,注意编译环境要换成jdk1.6才有compiler,单纯的jre没有compiler,会空指针错误
JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
(2)//文件管事器
StandardJavaFileManager fileMgr = jc.getStandardFileManager(null, null, null);
(3)//编译单元
Iterable units = fileMgr.getJavaFileObjects(file);
(4)//编译任务
CompilationTask t = jc.getTask(null, fileMgr, null, null, null, units);
(5)//编译
t.call();
(6)//把类load到内存里
URL[] urls = new URL[] {new URL("file:/"+System.getProperty("user.dir")+"/src/proxy/TankTimeProxy.class")};
URLClassLoader uc = new URLClassLoader(urls);
Class c = uc.loadClass("proxy.TankTimeProxy");
(7)//生成实例
//return c.newInstance(); //c.newInstance()会调用无参数的Construtor,若类没有无参的Constructor时会出错
Constructor ctr = c.getConstructor(Movable.class);
return ctr.newInstance(new Tank());
 
 
二、代码
1.Movable.java
2.Tank.java
3.Proxy.java
4.Client.java
1.Moveable.java
- package com.weiqinshian.proxy;
 - public
interface Moveable - {
 - public
void move(); - }
 
2.Tank.java
- package com.weiqinshian.proxy;
 - import java.util.Random;
 - public
class Tank implements Moveable - {
 - @Override
 - public
void move() - {
 - System.out.println("tank move........");
 - try
 - {
 - Thread.sleep(new Random().nextInt(10000));
 - } catch (InterruptedException e)
 - {
 - e.printStackTrace();
 - }
 - }
 - }
 
3.Proxy.java
- package com.weiqinshian.proxy;
 - import java.io.File;
 - import java.io.FileWriter;
 - import java.lang.reflect.Constructor;
 - import java.net.URL;
 - import java.net.URLClassLoader;
 - import javax.tools.JavaCompiler;
 - import javax.tools.StandardJavaFileManager;
 - import javax.tools.ToolProvider;
 - import javax.tools.JavaCompiler.CompilationTask;
 - public
class Proxy - {
 - public
static Object newProxyInstance() throws Exception - {
 - String rt = "\n\r";
 - // 动态代理文件的源码
 - String str = "package com.weiqinshian.proxy;" + rt +
 - "public class TankTimeProxy implements Moveable {" + rt +
 - "private Moveable m;" + rt +
 - "public TankTimeProxy(Moveable m) {" + rt + "this.m = m;" + rt + "}" + rt +
 - "@Override" + rt + "public void move() {" + rt + "System.out.println(\"Time Proxy start...........\");" + rt + "long start = System.currentTimeMillis();" + rt + "m.move();" + rt
 - + "long end = System.currentTimeMillis();" + rt + "System.out.println(\"花费时间:\"+(end - start));" + rt + "System.out.println(\"Time Proxy end...........\");" + rt + "}" + rt +
 - "}";
 - // 把源码写到java文件里
 - File file = new File("d:/src/com/weiqinshian/proxy/TankTimeProxy.java");
 - FileWriter fw = new FileWriter(file);
 - fw.write(str);
 - fw.flush();
 - fw.close();
 - // 编译源码,生成class,注意编译环境要换成jdk才有compiler,单纯的jre没有compiler,会空指针错误
 - JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
 - // 文件管事器
 - StandardJavaFileManager fileMgr = jc.getStandardFileManager(null, null, null);
 - // 编译单元
 - Iterable units = fileMgr.getJavaFileObjects(file);
 - // 编译任务
 - CompilationTask t = jc.getTask(null, fileMgr, null, null, null, units);
 - // 编译
 - t.call();
 - fileMgr.close();
 - // 把类load到内存里src\com\weiqinshian\proxy
 - URL[] urls = new URL[]
 - { new URL("file:/" + "d:/src/") };
 - System.out.println("file:/" + System.getProperty("user.dir") + "/src/com/weiqinshian/proxy/TankTimeProxy.class");
 - URLClassLoader uc = new URLClassLoader(urls);
 - Class c = uc.loadClass("com.weiqinshian.proxy.TankTimeProxy");
 - // 生成实例
 - // return c.newInstance();
 - // //c.newInstance()会调用无参数的Construtor,若类没有无参的Constructor时会出错
 - Constructor ctr = c.getConstructor(Moveable.class);
 - return ctr.newInstance(new Tank());
 - }
 - }
 
 
 
4.Client.java
- package com.weiqinshian.proxy;
 - public
class Client - {
 - public
static
void main(String[] args) throws Exception - {
 - Moveable m = (Moveable) Proxy.newProxyInstance();
 - m.move();// 感觉没有生成任何代理类
 - }
 - }
 
三、运行结果

 
 
三、问题引出
现在动态代理,动态生成的代理类是写死了的,是用字符串写死在类里面的,而且,只能动态生成实现了 Moveable接口的代理,如果要实现任意接口的代理应该怎么办? 那就不将动态生成代理类的字符串写死,动态拼接生成代理类。
代理模式--动态代理 修改成可以代理任意接口
一、概述
1.目标:把Proxy修改成可以代理任意接口及其任意方法,只要传接口名给newProxyInstance,就能动态生成实现了该接口的代理类。
2.思路:
(1)代理任意接口:把接口类型作为参数传给Proxy的newProxyInstance(Class interfze)
(2)代理任意方法:用interfze.getMethods()取出所有方法,拼接实现方法的字符串
 
 
二、代码
1.Movable.java
2.Tank.java
3.Proxy.java
4.Client.java
 
 
1.Movable.java
- package com.weiqinshian.proxy;
 - public
interface Moveable - {
 - public
void move(); - public
void stop(); - }
 
 
 
2.Tank.java
- package com.weiqinshian.proxy;
 - import java.util.Random;
 - public
class Tank implements Moveable - {
 - @Override
 - public
void move() - {
 - System.out.println("tank move........");
 - try
 - {
 - Thread.sleep(new Random().nextInt(10000));
 - } catch (InterruptedException e)
 - {
 - e.printStackTrace();
 - }
 - }
 - public
void stop() - {
 - System.out.println("Tank stopping.......");
 - }
 - }
 
3.Proxy.java
- package com.weiqinshian.proxy;
 - import java.io.File;
 - import java.io.FileWriter;
 - import java.lang.reflect.Constructor;
 - import java.lang.reflect.Method;
 - import java.net.URL;
 - import java.net.URLClassLoader;
 - import javax.tools.JavaCompiler;
 - import javax.tools.StandardJavaFileManager;
 - import javax.tools.ToolProvider;
 - import javax.tools.JavaCompiler.CompilationTask;
 - public
class Proxy - {
 - public
static Object newProxyInstance(Class interfze) throws Exception - {
 - String rt = "\n\r";
 - // 拼接"实现接口方法"的字符串
 - String methodStr = "";
 - for (Method m : interfze.getMethods())
 - {
 - // 取出方法的修饰符和返回值类型
 - String[] parts = m.toString().replace("abstract ", "").split("\\.");
 - String[] parts2 = parts[0].split("
"); - methodStr += "@Override" + rt + parts2[0] + "
" + parts2[1] + "
" + m.getName() + "() {" + rt + "System.out.println(\"Time Proxy start...........\");" + rt - + "long start = System.currentTimeMillis();" + rt + "m." + m.getName() + "();" + rt + "long end = System.currentTimeMillis();" + rt
 - + "System.out.println(\"花费时间:\"+(end - start));" + rt + "System.out.println(\"Time Proxy end...........\");" + rt + "}";
 - }
 - // 动态代理文件的源码
 - String str = "package com.weiqinshian.proxy; " + rt +
 - "public class TankTimeProxy implements " + interfze.getName() + " {" + rt +
 - "private " + interfze.getName() + " m;" + rt +
 - "public TankTimeProxy(" + interfze.getName() + " m) {" + rt + "this.m = m;" + rt + "}" + rt +
 - methodStr + rt +
 - "}";
 - // 把源码写到java文件里
 - File file = new File("d:/src/com/weiqinshian/proxy/TankTimeProxy.java");
 - FileWriter fw = new FileWriter(file);
 - fw.write(str);
 - fw.flush();
 - fw.close();
 - // 编译源码,生成class,注意编译环境要换成jdk才有compiler,单纯的jre没有compiler,会空指针错误
 - JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
 - // 文件管事器
 - StandardJavaFileManager fileMgr = jc.getStandardFileManager(null, null, null);
 - // 编译单元
 - Iterable units = fileMgr.getJavaFileObjects(file);
 - // 编译任务
 - CompilationTask t = jc.getTask(null, fileMgr, null, null, null, units);
 - // 编译
 - t.call();
 - fileMgr.close();
 - // 把类load到内存里src\com\weiqinshian\proxy
 - URL[] urls = new URL[]
 - { new URL("file:/" + "d:/src/") };
 - System.out.println("file:/" + System.getProperty("user.dir") + "/src/com/weiqinshian/proxy/TankTimeProxy.class");
 - URLClassLoader uc = new URLClassLoader(urls);
 - Class c = uc.loadClass("com.weiqinshian.proxy.TankTimeProxy");
 - // 生成实例
 - // return c.newInstance();
 - // //c.newInstance()会调用无参数的Construtor,若类没有无参的Constructor时会出错
 - Constructor ctr = c.getConstructor(interfze);
 - return ctr.newInstance(new Tank());
 - }
 - }
 
 
 
4.Client.java
- package com.weiqinshian.proxy;
 - public
class Client - {
 - public
static
void main(String[] args) throws Exception - {
 - Moveable m = (Moveable) Proxy.newProxyInstance(Moveable.class);// 方法参数可以传任意接口类型
 - m.move();
 - m.stop();
 - }
 - }
 
三、运行结果

TankTimeProxy 动态生成的类
- package com.weiqinshian.proxy;
 - public
class TankTimeProxy implements com.weiqinshian.proxy.Moveable { - private com.weiqinshian.proxy.Moveable m;
 - public TankTimeProxy(com.weiqinshian.proxy.Moveable m) {
 - this.m = m;
 - }
 - @Override
 - public
void stop() { - System.out.println("Time Proxy start...........");
 - long start = System.currentTimeMillis();
 - m.stop();
 - long end = System.currentTimeMillis();
 - System.out.println("花费时间:" + (end - start));
 - System.out.println("Time Proxy end...........");
 - }
 - @Override
 - public
void move() { - System.out.println("Time Proxy start...........");
 - long start = System.currentTimeMillis();
 - m.move();
 - long end = System.currentTimeMillis();
 - System.out.println("花费时间:" + (end - start));
 - System.out.println("Time Proxy end...........");
 - }
 - }
 
四、问题引出
上面这种方式生成的动态代理,只能生成时间上的代理。我要想生成一个log、权限代理,还是需要再写一个Proxy动态代理类,怎么解决这个问题?我们在可以在生成代理类的同时,调用一个别人指定给我的处理方式。
在代理里面调用方法的时候,方法前面加什么(比如:日志),后面加什么,不写死,由别人动态指定。方法的执行交给别人了执行,而执行的过程,可以由我们自己来定(多态)。
思路:将大问题分解为小问题
第一步:需要一个可以动态指定对某一方法进行处理的东西 (InvocationHandler 接口,方法调用处理器)
第二步:TimeHandler
代理模式-动态代理 修改成可以任意修改代理逻辑
一、概述
1.目标:动态代理的代理逻辑可以任意修改
2.思路:
(1)要把代理逻辑抽离,站在jvm的角度思考,应独立出InvocationHandler接口,并接收被代理的对象及方法作为参数invoke(Object o, Method m),并本身作为参数传给newProxyInstance(Class interfze,InvocationHandler handler)
(2)InvocationHandler本身聚合被代理类target,以便在target的方法前后增加代理逻辑
3.知识点:
(1)按名字找方法java.lang.reflect.Method md = proxy.Movable.class.getMethod("stop");
(2)按"."拆分字符串:String [] parts = m.toString().replace("abstract ", "").split("\\.");
 
 
二、代码
1.InvocationHandler.java
2.TimeHandler.java
3.Movable.java
4.Tank.java
5.Proxy.java
6.Client.java
 
 
1.InvocationHandler.java
- package com.weiqinshian.proxy;
 - import java.lang.reflect.Method;
 - public
interface InvocationHandler - {
 - public
void invoke(Object o, Method m); - }
 
2.TimeHandler.java
- package com.weiqinshian.proxy;
 - import java.lang.reflect.Method;
 - public
class TimeHandler implements InvocationHandler - {
 - // 保留被代理的对象
 - private Object target;
 - public TimeHandler(Object target)
 - {
 - this.target = target;
 - }
 - public
void invoke(Object o, Method m) - {
 - System.out.println("Time Proxy start...........");
 - long start = System.currentTimeMillis();
 - try
 - {
 - // 除了静态方法,方法的调用都要先已知对象,所以要把对象o作为参数传进去
 - m.invoke(target);
 - } catch (Exception e)
 - {
 - e.printStackTrace();
 - }
 - long end = System.currentTimeMillis();
 - System.out.println("花费时间:" + (end - start));
 - System.out.println("Time Proxy end...........");
 - }
 - }
 
3.Moveable.java
- package com.weiqinshian.proxy;
 - public
interface Moveable - {
 - public
void move(); - public
void stop(); - }
 
4.Tank.java
- package com.weiqinshian.proxy;
 - import java.util.Random;
 - public
class Tank implements Moveable - {
 - @Override
 - public
void move() - {
 - System.out.println("tank move........");
 - try
 - {
 - Thread.sleep(new Random().nextInt(10000));
 - } catch (InterruptedException e)
 - {
 - e.printStackTrace();
 - }
 - }
 - public
void stop() - {
 - System.out.println("Tank stopping.......");
 - }
 - }
 
 
 
5.Proxy.java
- package com.weiqinshian.proxy;
 - import java.io.File;
 - import java.io.FileWriter;
 - import java.lang.reflect.Constructor;
 - import java.lang.reflect.Method;
 - import java.net.URL;
 - import java.net.URLClassLoader;
 - import javax.tools.JavaCompiler;
 - import javax.tools.StandardJavaFileManager;
 - import javax.tools.ToolProvider;
 - import javax.tools.JavaCompiler.CompilationTask;
 - public
class Proxy - {
 - public
static Object newProxyInstance(Class interfze, InvocationHandler handler) throws Exception - {
 - String rt = "\n\r";
 - // 拼接"实现接口方法"的字符串
 - String methodStr = "";
 - for (Method m : interfze.getMethods())
 - {
 - // 取出方法的修饰符和返回值类型
 - String[] parts = m.toString().replace("abstract ", "").split("\\.");
 - String[] parts2 = parts[0].split("
"); - methodStr += "@Override" + rt + parts2[0] + "
" + parts2[1] + "
" + m.getName() + "() {" + rt + "try{" + rt + "java.lang.reflect.Method md = " + interfze.getName() + ".class.getMethod(\"" - + m.getName() + "\");" + rt +
 - // 传this进去其实没什么用,invoke实际是调用target的方法m.invoke(target)
 - "handler.invoke(this, md);" + rt + "}catch(Exception e){" + rt + " e.printStackTrace();" + rt + "}" + rt + "}" + rt;
 - }
 - // 动态代理文件的源码
 - String str = " package com.weiqinshian.proxy; " + rt +
 - "public class TankTimeProxy implements " + interfze.getName() + " {" + rt +
 - // 聚合Handler
 - "private InvocationHandler handler;" + rt +
 - "public TankTimeProxy(InvocationHandler handler) {" + rt + "this.handler = handler;" + rt + "}" + rt + methodStr + rt + "}";
 - // 把源码写到java文件里
 - File file = new File("d:/src/com/weiqinshian/proxy/TankTimeProxy.java");
 - FileWriter fw = new FileWriter(file);
 - fw.write(str);
 - fw.flush();
 - fw.close();
 - // 编译源码,生成class,注意编译环境要换成jdk才有compiler,单纯的jre没有compiler,会空指针错误
 - JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
 - // 文件管事器
 - StandardJavaFileManager fileMgr = jc.getStandardFileManager(null, null, null);
 - // 编译单元
 - Iterable units = fileMgr.getJavaFileObjects(file);
 - // 编译任务
 - CompilationTask t = jc.getTask(null, fileMgr, null, null, null, units);
 - // 编译
 - t.call();
 - fileMgr.close();
 - // 把类load到内存里src\com\weiqinshian\proxy
 - URL[] urls = new URL[]
 - { new URL("file:/" + "d:/src/") };
 - System.out.println("file:/" + System.getProperty("user.dir") + "/src/com/weiqinshian/proxy/TankTimeProxy.class");
 - URLClassLoader uc = new URLClassLoader(urls);
 - Class c = uc.loadClass("com.weiqinshian.proxy.TankTimeProxy");
 - // 生成实例
 - // return c.newInstance();
 - // //c.newInstance()会调用无参数的Construtor,若类没有无参的Constructor时会出错
 - // Constructor ctr = c.getConstructor(interfze);
 - Constructor ctr = c.getConstructor(InvocationHandler.class);
 - return ctr.newInstance(handler);
 - }
 - }
 
6.Client.java
作为客户来讲,调用这个方法的时候传了接口,我就知道方法返回的对象是实现了那个接口的,所以,强制转换为接口,这个肯定是没有什么问题的,往里面传new timeHandler,我自己要做什么样的代理的实现是由我自己来决定的
- package com.weiqinshian.proxy;
 - public
class Client - {
 - public
static
void main(String[] args) throws Exception - {
 - Moveable m = (Moveable) Proxy.newProxyInstance(Moveable.class, new TimeHandler(new Tank()));//
 - m.move();
 - m.stop();
 - }
 - }
 
 
 
三、运行结果

四、动态生成代码
- package com.weiqinshian.proxy;
 - import java.lang.reflect.InvocationHandler;
 - public
class TankTimeProxy implements com.weiqinshian.proxy.Moveable { - private InvocationHandler handler;
 - public TankTimeProxy(InvocationHandler handler) {
 - this.handler = handler;
 - }
 - @Override
 - public
void stop() { - try {
 - java.lang.reflect.Method md = com.weiqinshian.proxy.Moveable.class.getMethod("stop");
 - handler.invoke(this, md);
 - } catch (Exception e) {
 - e.printStackTrace();
 - }
 - }
 - @Override
 - public
void move() { - try {
 - java.lang.reflect.Method md = com.weiqinshian.proxy.Moveable.class.getMethod("move");
 - handler.invoke(this, md);
 - } catch (Exception e) {
 - e.printStackTrace();
 - }
 - }
 - }
 

CGLIB 和ASM 可以直接修改二进制码实现动态代理
CGLIB(Code Generation Library)是一个开源项目!
是一个强大的,高性能,高质量的Code生成类库,它可以在运行期扩展Java类与实现Java接口。Hibernate用它来实现PO(Persistent Object 持久化对象)字节码的动态生成。
ASM 是一个 Java 字节码操控框架。它能够以二进制形式修改已有类或者动态生成类。ASM 可以直接产生二进制 class 文件,也可以在类被加载入 Java 虚拟机之前动态改变类行为。ASM 从类文件中读入信息后,能够改变类行为,分析类信息,甚至能够根据用户要求生成新类。
Java-马士兵动态代理模式的更多相关文章
- Java设计模式—Proxy动态代理模式
		
代理:设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 图 1. 代 ...
 - java学习之动态代理模式
		
package com.gh.dynaproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Metho ...
 - JAVA动态代理模式(从现实生活角度理解代码原理)
		
所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...
 - 黑马程序员:Java基础总结----静态代理模式&动态代理
		
黑马程序员:Java基础总结 静态代理模式&动态代理 ASP.Net+Android+IO开发 . .Net培训 .期待与您交流! 静态代理模式 public class Ts { ...
 - Java静态代理与动态代理模式的实现
		
前言: 在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总找不到时间去找他,他也没办法.后来,房东想了一个办法,他找到 ...
 - java jdk动态代理模式举例浅析
		
代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...
 - Java的三种代理模式(Spring动态代理对象)
		
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
 - Java 代理模式(二) Java中的动态代理
		
动态代理类 Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类: 1.Interface InvocationHandler 该接口中仅定义了一个方法: Objec ...
 - 关于java动态代理模式
		
1. 动态代理 动态代理就是通过代理类是代理类与相关接口不直接发生联系,而在运行期(Runtime)实现动态关联. 动态代理主要用到java.lang.reflect包中的两个类,Invocation ...
 
随机推荐
- 家庭路由器设置以及win10链接无线不显示登录密码 直接提示链接出错问题解决
			
家庭路由器设置 网线插入WAN口,用网客户端接在LAN口,就是路由器模式 LAN→WAN设置:电脑→第二个路由器LAN→进入设置界面: 网络参数→WAN口设置→WAN口连接类型→动态IP→保存. 网络 ...
 - spring aop 环绕通知around和其他通知的区别
			
前言: spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别: 1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知 是不能决定的,他们只 ...
 - JVM内存管理------垃圾搜集器参数精解
			
本文是GC相关的最后一篇,这次LZ只是罗列一下hotspot JVM中垃圾搜集器相关的重点参数,以及各个参数的解释.废话不多说,这就开始. 垃圾搜集器文章传送门 JVM内存管理------JAVA语言 ...
 - stdlib.h stdio.h
			
stdlib.h 即standard library标准库头文件.stdlib.h里面定义了五种类型.一些宏和通用工具函数. 类型例如size_t.wchar_t.div_t.ldiv_t和lldiv ...
 - 集合List内容
			
集合List内容 这次我们学习的主要内容为:集合框架 List 一 集合框架介绍 List集合与数组的区别: 不同点:1> 数组的长度在使用前必须确定,一旦确定不能改变.而List集合长度 ...
 - java ArrayList 实现
			
关于ArrayList的实现和原理,原文出处:http://www.cnblogs.com/ITtangtang/p/3948555.html 我觉得他写的非常好,真的很好. 做一个记录和总结吧 pu ...
 - hive 普通创建表和跟新列操作
			
创建表 CREATE TABLE if not exists student ( student_id int, sex int, address String, email String ) 这里需 ...
 - sql面试题一 学生成绩
			
sql面试题一 学生成绩 原帖链接:http://topic.csdn.net/u/20081020/15/1ABF54D0-F401-42AB-A75E-DF90027CEBA0.html 表架 ...
 - 与你相遇好幸运,Sailsjs查询
			
sailsjs 原生查询 ------------------------------------- Lands.native(function(err, collection) { if (err) ...
 - Tensorflow 实现稠密输入数据的逻辑回归二分类
			
首先 实现一个尽可能少调用tf.nn模块儿的,自己手写相关的function import tensorflow as tf import numpy as np import melt_da ...