代理模式是一种架构型模式,表现出来就是一个类代表另一个类的功能,一般用在想对访问一个类的时候做一些控制,同时又不想影响正常的业务,这种代理模式在现实的生活中应用的也非常的广泛,我用穷举法给举几个好理解的例子:

1.像我们在大城市里的中介找房子的网站,房东、租户、中间商的三角关系,就是典型的代理模式。

2.还有就是帮助人找媳妇的媒婆,也是代理模式。

3.还有黄牛党等等还有很多。

正向代理和反向代理的区别:

1.正向代理代理的是用户,用户->代理服务器->谷歌的原网站模式,通过代理服务器访问谷歌。

2.反向代理代理的是服务器,比如我们访问百度的时候,其实感觉像访问一台电脑,其实在后面有成千上万台的服务器,比如通过代理服务器代理后台的服务器进行分发请求。

下面咱们通过代码进行一步一步的进行演进:

静态代理

父亲给儿子找对象,从代码不灵活进行演变。

package pattern.proxy;
/**
* 父亲给儿子找对象,父亲有儿子的引用
* 才可以给儿子找对象
*/
public class Father {
private Son person;
public Father(Son person){
this.person=person;
}
public void findLove(){
System.out.println("根据你的要求物色");
this.person.findLove();
System.out.println("双色父母是不是同意");
}
}
package pattern.proxy;
public class Son {
public void findLove(){
System.out.println("找对象,腿长的,漂亮的");
}
}
package pattern.proxy;
public class ProxyTest {
public static void main(String[] args) {
//父亲给儿子找对象
Father father=new Father(new Son());
father.findLove();
}
}

下面使用接口进行改造:

package pattern.proxy;
public interface Person {
public void findLove();
public void findHouse();
}
package pattern.proxy;
/**
* 父亲给儿子找对象,父亲有儿子的引用
* 才可以给儿子找对象
*/
public class Father implements Person {
private Person person;
public Father(Person person){
this.person=person;
}
public void findLove(){
System.out.println("根据你的要求物色");
person.findLove();
System.out.println("双色父母是不是同意");
}
@Override
public void findHouse() {
person.findHouse();
}
}
package pattern.proxy;
public class Son implements Person {
public void findLove(){
System.out.println("找对象,腿长的,漂亮的");
}
@Override
public void findHouse() {
System.out.println("找房子了");
}
}
package pattern.proxy;
public class ProxyTest {
public static void main(String[] args) {
//父亲给儿子找对象
Person father=new Father(new Son());
father.findLove();
}
}

其实如果接口里面代理的方法太多,是比较麻烦的,下面使用动态代理进行改造。

JDK动态代理

package pattern.proxy.jdk;
public interface Person {
public void findLove();
}
package pattern.proxy.jdk;
public class XieMu implements Person {
public void findLove(){
System.out.println("xiemu要找对象了,要求比较高,漂亮,美");
}
}
package pattern.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkMeiPo implements InvocationHandler {
//被代理的对象
private Person target;
public Object getInstance(XieMu target){
this.target=target;
Class<?> clazz=target.getClass();
//生成一个新的对象,通过字节码重组
return Proxy.newProxyInstance(clazz.getClassLoader(),clazz.getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是媒婆,我要给你找对象,现在已经拿到你的需求");
System.out.println("开始物色");
method.invoke(target,args);
System.out.println("如果合适,那就办事了");
return null;
}
}
package pattern.proxy.jdk;
public class JdkMeiPoTest {
public static void main(String[] args) {
Person person=(Person) new JdkMeiPo().getInstance(new XieMu());
person.findLove();
}
}

这里面的JdkMeiPo持有被代理人的对象,同时实现InvocationHandler接口,还有一个Proxy.newProxyInstance()的方法用来生成一个新的对象,通过字节码重组。

cglib动态代理

cglib是面向方法就可以进行代理,但是是通过字节码重组动态生成的接口。

package pattern.proxy.cglib;
public class ZhangSan {
public void findLove(){
System.out.println("漂亮的美美");
}
}
package pattern.proxy.cglib;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class CglibMeiPo implements MethodInterceptor{
public Object getInstance(Class<?> clazz) throws Exception{
Enhancer enhancer=new Enhancer();
//要把哪个设置为即将生成的新类父类
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
} @Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//业务的增强
System.out.println("我是媒婆,我要给你找对象,现在已经拿到你的需求");
System.out.println("开始物色");
methodProxy.invokeSuper(o,objects);
System.out.println("如果合适,那就办事了");
return null;
}
}
package pattern.proxy.cglib;
public class CglibTest {
public static void main(String[] args) throws Exception {
ZhangSan obj=(ZhangSan) new CglibMeiPo().getInstance(ZhangSan.class);
obj.findLove();
}
}

手写JDK动态代理

把动态代理生成的代理类保存到文件里:

package pattern.proxy.jdk;
import sun.misc.ProxyGenerator;
import java.io.FileOutputStream;
public class JdkMeiPoTest {
public static void main(String[] args) throws Exception {//原理:
//1、拿到被代理对象的引用,并且获取到它的所有的接口,反射获取
//2、JDK Proxy类重新生成一个新的类、同时新的类要实现被代理类所有实现的所有的接口
//3、动态生成Java代码,把新加的业务逻辑方法由一定的逻辑代码去调用(在代码中体现)
//4、编译新生成的Java代码.class
//5、再重新加载到JVM中运行
//以上这个过程就叫字节码重组
//JDK中有个规范,只要要是$开头的一般都是自动生成的
byte[] bytes=ProxyGenerator.generateProxyClass("$Proxy0",new Class[]{Person.class});
FileOutputStream fos=new FileOutputStream("D://$proxy0.class");
fos.write(bytes);
fos.flush();
fos.close();
}
}

生成的$Proxy0文件:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import pattern.proxy.jdk.Person; public final class $Proxy0 extends Proxy implements Person {
private static Method m1;
//m3调用的是findLove(),从下面的静态快可以看出来
private static Method m3;
private static Method m2;
private static Method m0; public $Proxy0(InvocationHandler var1) throws {
super(var1);
}

//Object对象的
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}

//代理类实现了Person类,重写了findLove的方法
public final void findLove() throws {
try {
//$Proxy0继承了Proxy类,就可以用Proxy里的InvocationHandler里的h,这个其实就是JdkMeiPo实现的接口InvocationHander.
//调用JdkMeiPo的invoke方法,传入当先的对象和invoke中执行的findLove方法,参数为空
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}

//Object对象的
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}

//Object对象的
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
} static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("pattern.proxy.jdk.Person").getMethod("findLove");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
package java.lang.reflect;
import java.lang.ref.WeakReference;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.IdentityHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiFunction;
import sun.misc.ProxyGenerator;
import sun.misc.VM;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
public class Proxy implements java.io.Serializable { private static final long serialVersionUID = -2222568056686623797L; /** parameter types of a proxy class constructor */
private static final Class<?>[] constructorParams =
{ InvocationHandler.class }; /**
* a cache of proxy classes
*/
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory()); /**
* the invocation handler for this proxy instance.
* @serial
*/
protected InvocationHandler h; /**
* Prohibits instantiation.
*/
private Proxy() {
} protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
} @CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
throws IllegalArgumentException
{
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
} return getProxyClass0(loader, intfs);
} private static void checkProxyAccess(Class<?> caller,
ClassLoader loader,
Class<?>... interfaces)
{
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = caller.getClassLoader();
if (VM.isSystemDomainLoader(loader) && !VM.isSystemDomainLoader(ccl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
} /**
* Generate a proxy class. Must call the checkProxyAccess method
* to perform permission checks before calling this.
*/
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
} // If the proxy class defined by the given loader implementing
// the given interfaces exists, this will simply return the cached copy;
// otherwise, it will create the proxy class via the ProxyClassFactory
return proxyClassCache.get(loader, interfaces);
} /*
* a key used for proxy class with 0 implemented interfaces
*/
private static final Object key0 = new Object(); /*
* Key1 and Key2 are optimized for the common use of dynamic proxies
* that implement 1 or 2 interfaces.
*/ /*
* a key used for proxy class with 1 implemented interface
*/
private static final class Key1 extends WeakReference<Class<?>> {
private final int hash; Key1(Class<?> intf) {
super(intf);
this.hash = intf.hashCode();
} @Override
public int hashCode() {
return hash;
} @Override
public boolean equals(Object obj) {
Class<?> intf;
return this == obj ||
obj != null &&
obj.getClass() == Key1.class &&
(intf = get()) != null &&
intf == ((Key1) obj).get();
}
} /*
* a key used for proxy class with 2 implemented interfaces
*/
private static final class Key2 extends WeakReference<Class<?>> {
private final int hash;
private final WeakReference<Class<?>> ref2; Key2(Class<?> intf1, Class<?> intf2) {
super(intf1);
hash = 31 * intf1.hashCode() + intf2.hashCode();
ref2 = new WeakReference<Class<?>>(intf2);
} @Override
public int hashCode() {
return hash;
} @Override
public boolean equals(Object obj) {
Class<?> intf1, intf2;
return this == obj ||
obj != null &&
obj.getClass() == Key2.class &&
(intf1 = get()) != null &&
intf1 == ((Key2) obj).get() &&
(intf2 = ref2.get()) != null &&
intf2 == ((Key2) obj).ref2.get();
}
} /*
* a key used for proxy class with any number of implemented interfaces
* (used here for 3 or more only)
*/
private static final class KeyX {
private final int hash;
private final WeakReference<Class<?>>[] refs; @SuppressWarnings("unchecked")
KeyX(Class<?>[] interfaces) {
hash = Arrays.hashCode(interfaces);
refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
refs[i] = new WeakReference<>(interfaces[i]);
}
} @Override
public int hashCode() {
return hash;
} @Override
public boolean equals(Object obj) {
return this == obj ||
obj != null &&
obj.getClass() == KeyX.class &&
equals(refs, ((KeyX) obj).refs);
} private static boolean equals(WeakReference<Class<?>>[] refs1,
WeakReference<Class<?>>[] refs2) {
if (refs1.length != refs2.length) {
return false;
}
for (int i = 0; i < refs1.length; i++) {
Class<?> intf = refs1[i].get();
if (intf == null || intf != refs2[i].get()) {
return false;
}
}
return true;
}
} /**
* A function that maps an array of interfaces to an optimal key where
* Class objects representing interfaces are weakly referenced.
*/
private static final class KeyFactory
implements BiFunction<ClassLoader, Class<?>[], Object>
{
@Override
public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // the most frequent
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
} /**
* A factory function that generates, defines and returns the proxy class given
* the ClassLoader and array of interfaces.
*/
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{ private static final String proxyClassNamePrefix = "$Proxy"; private static final AtomicLong nextUniqueNumber = new AtomicLong(); @Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) { Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
/*
* Verify that the Class object actually represents an
* interface.
*/
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
*/
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
} String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL; /*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
*/
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
} if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
long num = nextUniqueNumber.getAndIncrement();
String proxyName = proxyPkg + proxyClassNamePrefix + num;
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) { throw new IllegalArgumentException(e.toString());
}
}
} //loalder类加载器
//实现的接口数组
//h所有动态代理类的方法调用,都会交由InvocationHandler接口实现类里的invoke()方法去处理。这是动态代理的关键所在
@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);
}
} private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
ClassLoader ccl = caller.getClassLoader();
ClassLoader pcl = proxyClass.getClassLoader(); // do permission check if the caller is in a different runtime package
// of the proxy class
int n = proxyClass.getName().lastIndexOf('.');
String pkg = (n == -1) ? "" : proxyClass.getName().substring(0, n); n = caller.getName().lastIndexOf('.');
String callerPkg = (n == -1) ? "" : caller.getName().substring(0, n); if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
}
}
}
}
public static boolean isProxyClass(Class<?> cl) {
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
{
if (!isProxyClass(proxy.getClass())) {
throw new IllegalArgumentException("not a proxy instance");
} final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class<?> ihClass = ih.getClass();
Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
} return ih;
} private static native Class<?> defineClass0(ClassLoader loader, String name,
byte[] b, int off, int len);
}

下面实现一个自己的动态代理:

package pattern.proxy.custom;
public interface Person {
public void findLove();
}
package pattern.proxy.custom;
public class XieMu implements Person {
public void findLove(){
System.out.println("xiemu要找对象了,要求比较高,漂亮,美");
}
}
package pattern.proxy.custom;
import java.lang.reflect.Method; public class CustomMeiPo implements JavaInvocationHandler { private Person target; public Object getInstance(Person target){
this.target=target;
Class<?> clazz=target.getClass();
return JavaProxy.newProxyInstance(new JavaClassLoader(),clazz.getInterfaces(),this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("我是媒婆,我要给你找对象,现在已经拿到你的需求");
System.out.println("开始物色");
method.invoke(target,args);
System.out.println("如果合适,那就办事了");
return null;
}
}

根据kdk里面的主要java类创建自定义的类:

package pattern.proxy.custom;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Iterator; public class JavaProxy { public static final String Ln="\r\n"; public static Object newProxyInstance(JavaClassLoader classLoader,
Class<?>[] interfaces,
JavaInvocationHandler h){
try {
//1.动态生成源代码.java文件
String src=generateSrc(interfaces);
//2.java文件输出到磁盘
String filePath=JavaProxy.class.getResource("").getPath();
System.out.println(filePath);
File file=new File(filePath+"$Proxy0.java");
FileWriter fw=new FileWriter(file);
fw.write(src);
fw.flush();
fw.close();
//3.把生成的.java文件编译成.class文件
JavaCompiler compiler= ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager manage=compiler.getStandardFileManager(null,null,null);
Iterable iterable=manage.getJavaFileObjects(file);
JavaCompiler.CompilationTask task=compiler.getTask(null,null,null,null,null,null);
task.call();
manage.close();
//4.编译生成的.class文件加载到JVM中来
Class proxyClass=classLoader.findClass("$Proxy0");
Constructor c=proxyClass.getConstructor(JavaInvocationHandler.class);
file.delete();
//5.返回字节码重组后新的对象
return c.newInstance(h);
}catch (Exception e){
e.printStackTrace();
}
return null;
} public static String generateSrc(Class<?>[] interfaces){
StringBuffer sb=new StringBuffer();
sb.append("package pattern.proxy.custom;" + Ln);
sb.append("import java.lang.reflect.Method;"+ Ln);
sb.append("public class $Proxy0 implements " + interfaces[0].getName() + "{" + Ln);
sb.append("public JavaInvocationHandler h;" + Ln);
sb.append("public $Proxy0(JavaInvocationHandler h) { "+Ln);
sb.append("this.h=h;"+Ln);
sb.append("}"+Ln); for (Method m:interfaces[0].getMethods()){
sb.append("public "+ m.getReturnType().getName() + " " +m.getName() + "(){"+ Ln);
sb.append("try{"+Ln);
sb.append("Method m="+interfaces[0].getName()+".class.getMethod(\"" + m.getName() + "\",new Class[]{});" + Ln);
sb.append("this.h.invoke(this,m,null);"+Ln);
sb.append("}catch(Throwable e){" + Ln);
sb.append("e.printStackTrace();" + Ln);
sb.append("}" + Ln);
sb.append("}" + Ln);
}
sb.append("}" + Ln);
return sb.toString();
}
}
package pattern.proxy.custom;
import java.lang.reflect.Method;
public interface JavaInvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
package pattern.proxy.custom;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class JavaClassLoader extends ClassLoader { private File classPathFile; public JavaClassLoader(){
String classPath=JavaClassLoader.class.getResource("").getPath();
this.classPathFile=new File(classPath);
} @Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String className=JavaClassLoader.class.getPackage().getName()+"."+name;
if(classPathFile!=null){
File classFile=new File(classPathFile,name.replaceAll("\\.","/")+".class");
if(classFile.exists()){
FileInputStream in=null;
ByteArrayOutputStream out=null;
try {
in=new FileInputStream(classFile);
out=new ByteArrayOutputStream();
byte[] buff=new byte[1024];
int len;
while ((len=in.read(buff))!=-1){
out.write(buff,0,len);
}
return defineClass(className,out.toByteArray(),0,out.size());
}catch (Exception e){
e.printStackTrace();
}finally {
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
}

测试类:

package pattern.proxy.custom;

public class CustomProxyTest {

    public static void main(String[] args) {
Person person=(Person) new CustomMeiPo().getInstance(new XieMu());
person.findLove();
}
}

效果:

我是媒婆,我要给你找对象,现在已经拿到你的需求
开始物色
xiemu要找对象了,要求比较高,漂亮,美
如果合适,那就办事了

喜欢和喜欢学习的一起交流技术!

代理模式精讲(手写JDK动态代理)的更多相关文章

  1. Java代理模式精讲之静态代理,动态代理,CGLib代理

    代理(Proxy)是一种设计模式,通俗的讲就是通过别人达到自己不可告人的目的(玩笑). 如图: 代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象 这三个代理模式,就 ...

  2. JDK动态代理深入理解分析并手写简易JDK动态代理(下)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...

  3. JDK动态代理深入理解分析并手写简易JDK动态代理(上)

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...

  4. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

  5. JDK动态代理浅析

    原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2018-06-29/17.html 作者:夜月归途 出处:http://www.guitu ...

  6. jdk动态代理和cglib动态代理底层实现原理超详细解析(jdk动态代理篇)

    代理模式是一种很常见的模式,本文主要分析jdk动态代理的过程 1.举例 public class ProxyFactory implements InvocationHandler { private ...

  7. Java-基础-JDK动态代理

    1. 简介 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 比如:我们在调用 ...

  8. SSM-Spring-09:Spring中jdk动态代理

    ------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- JDK动态代理: 为何叫JDK动态代理呢? 所谓JDK,jdk是java开发工具包,它里面包含了一个动态代理的 ...

  9. java jdk动态代理学习记录

    转载自: https://www.jianshu.com/p/3616c70cb37b JDK自带的动态代理主要是指,实现了InvocationHandler接口的类,会继承一个invoke方法,通过 ...

随机推荐

  1. ubuntu 12.04上安装QQ2013(转载)

    转自:http://www.cnblogs.com/wocn/p/linux_ubuntu_QQ_install.html 环境介绍: OS:Ubuntu12.04 64bit QQ:WineQQ20 ...

  2. APP支付宝登录第三方授权如何签约入口在哪里

    最近,公司项目要接入支付宝授权登录,第三方SDK接入过不少,一顿按照流程操作.到签约的步骤的时候就把我难住了,入口一直找不到.然后在文档中心搜索“支付宝登录签约”,找到一个申请地址.心想终于找到你了, ...

  3. Java标识符的习惯命名规范

    1 常量标识符:全部用大写字母和下划线表示.如SALES_MAX 2 类名或接口名:标识符用大写字母开头.如CreditCard 3 变量名和方法名:以小写字母开头,单词之间不要有分隔符,第二 及后面 ...

  4. 安装11g 数据库

    出现问题解决: 1.首先确认下载的安装包完整性.2解压包的时候,按顺序解压,解压第一个包后,解压第二个包的时候,要把解压地址与解压第二包的地址要一样. 安装的时候,需要把两个压缩包都解压,并将目录wi ...

  5. 准确计算CoreText高度的方法:

    - (int)getAttributedStringHeightWithString:(NSAttributedString *) string WidthValue:(int) width { ; ...

  6. 转 Dock 外 命令解析

    RUN vs CMD vs ENTRYPOINT - 每天5分钟玩转 Docker 容器技术(17) 小结: run 主要是安装镜像,安装软件. CMD 设置容器启动后默认执行的命令及其参数,但 CM ...

  7. shell 调试 `<<' is not matched

    我的这段脚本,验证数据库连接是否正常: #! /bin/sh...while ..do....sqlplus $user/ $passwd@$sid  <<!quit;! ... 单独执行 ...

  8. 200 Number of Islands 岛屿的个数

    给定 '1'(陆地)和 '0'(水)的二维网格图,计算岛屿的数量.一个岛被水包围,并且通过水平或垂直连接相邻的陆地而形成.你可以假设网格的四个边均被水包围.示例 1:11110110101100000 ...

  9. 关于如何读取XML文件的一个简单方法

    在平时开发系统功能的时候,我们经常会碰到一些需求需要经常性的发生变化,比如 系统版本.更新日志 等等.这个时候用一个XML文件来替代数据库,就会变的简便很多. 前段时候我也正好需要改个需求,是关于客户 ...

  10. [转]Walkthrough: Your First F# Program

    本文转自:http://msdn.microsoft.com/en-us/library/vstudio/dd233160(v=vs.100).aspx   Visual Studio 2010 in ...