静态代理和动态代理

1.静态代理

package study.proxy.ststic;
/**
 * 接口
 * 一个人可以被代理的行为
 * @author an
 *
 */
public interface PersonAction {
	
	public void buyHouse();
	
	public void findJob();
	
}

package study.proxy.ststic;
/**
 * 工人
 * @author an
 *
 */
public class Worker implements PersonAction {

	@Override
	public void buyHouse() {
		System.out.println("工人:我要买一套两居室的价格在30万左右的房子");
	}

	@Override
	public void findJob() {
		System.out.println("工人:我想找一个不拖欠工资的工作");
	}

}
package study.proxy.ststic;
/**
 * 白领
 * @author an
 *
 */
public class WhiteCollar implements PersonAction {

	@Override
	public void buyHouse() {
		System.out.println("白领:我想买一套交通方便的房子,面积不要太大");
	}

	@Override
	public void findJob() {
		System.out.println("白领:我想找一份加班少待遇好的公司");
	}

}
package study.proxy.ststic;
/**
 * 我们是代理各种需求的中介
 * @author an
 *
 */
public class Agency implements PersonAction {
	
	private PersonAction person;
	
	public Agency(PersonAction person){
		this.person=person;
	}
	
	@Override
	public void buyHouse() {
		System.out.println("中介:您好,欢迎选择购房中介,您有什么需求?");
		person.buyHouse();
		System.out.println("中介:我的我们尽快帮您找到合适的房源");
	}

	@Override
	public void findJob() {
		System.out.println("中介:您好,欢迎光临工作无忧,您对工作有什么需求?");
		person.findJob();
		System.out.println("中介:感谢您的光临,我们尽快帮你 匹配合适的岗位。");
	}

}

package study.proxy.ststic;

public class AgencyTest {
	
	public static void main(String[] args) {
		Worker worker = new Worker();
		WhiteCollar wc = new WhiteCollar();
		
		Agency agency1 = new Agency(worker);
		agency1.buyHouse();
		agency1.findJob();
		System.out.println();
		Agency agency2 = new Agency(wc);
		agency2.buyHouse();
		agency2.findJob();
	}
	
}

2.JDK动态代理

package study.proxy.JDK;
/**
 * 目标类要实现的接口
 * @author an
 *
 */
public interface JDKDemoInter {
	
	public void detailShow(String s);
	
}
package study.proxy.JDK;
/**
 * 要被代理的类
 * 必须要有实现的接口
 * @author an
 *
 */
public class JDKClassDemo implements JDKDemoInter{
	
	private String name;
	
	public void detailShow(String s){
		System.out.println("你好我是JDKClassDemo,你输入的是"+s);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
	
}

package study.proxy.JDK;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * jdk动态代理
 * 使用java.lang.reflect.Proxy类来实现代理
 * @author an
 *
 */
public class JDKProxy1 {
	
	//被代理的目标对象
	private Object obj;
	
	public JDKProxy1(Object obj){
		this.obj = obj;
	}
	
	//生成代理对象
	/**
	 * ClassLoader 对象的类加载器
	 * Class<?>[] interfaces 目标对象实现的接口类型  
	 * InvocationHandler 事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
	 * @return
	 */
	public Object getProxyInstance(){
		return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),
				new InvocationHandler(){
					@Override
					public Object invoke(Object proxy, Method method,
							Object[] args) throws Throwable {
						System.out.println("执行前");
						Object returnObj = method.invoke(obj, args);
						System.out.println("执行后");
						return returnObj;
					}});
	}
	
}
package study.proxy.JDK;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * JDK动态代理的实现2
 * @author an
 *
 */
public class JDKProxy2 implements InvocationHandler{
	
	private Object obj;
	
	public Object getInstance(Object objc){
		this.obj=objc;
		return Proxy.newProxyInstance(objc.getClass().getClassLoader(), objc.getClass().getInterfaces(), this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("执行前");
		//第一个参数必须传obj
		Object returnObj = method.invoke(this.obj, args);
		System.out.println("执行后");
		return returnObj;
	}
	
	
	
}

package study.proxy.JDK;

public class JDKProxyTest {
	public static void main(String[] args) {
		
		JDKClassDemo demo = new JDKClassDemo();
		JDKDemoInter proxyDemo = (JDKDemoInter)new JDKProxy1(demo).getProxyInstance();
		proxyDemo.detailShow("000");
		
		
		JDKClassDemo demo1 = new JDKClassDemo();
		JDKDemoInter proxyDemo1 = (JDKDemoInter)new JDKProxy2().getInstance(demo1);
		proxyDemo1.detailShow("111");
		
		
	}
}

3.cglib动态代理

package study.proxy.Cglib;
/**
 * 被代理的目标类
 * 不需要实现接口
 * 代理的类不能为final,否则报错
 * 目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法
 * @author an
 *
 */
public class CglibClass {
	
	public void say(){
		System.out.println("this is CglibClass");
	}
	
	public static void say1(){
		System.out.println("this is static");
	}
	
	public final void say2(){
		System.out.println("this is final");
	}
	
}
package study.proxy.Cglib;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

/**
 * cglib代理类
 * Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,
 * 例如Spring AOP和synaop,为他们提供方法的interception(拦截)
 * 
 * Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类
 * 
 * Cglib代理,也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展.
 * @author an
 *
 */
public class CglibProxy implements MethodInterceptor{
	
	//目标对象
	private Object obj;
	
	public CglibProxy(Object obj){
		this.obj=obj;
	}
	
	//生成代理对象
	public Object getProxyInstance(){
		//设置工具类
		Enhancer en = new Enhancer();
		//设置父类
		en.setSuperclass(obj.getClass());
		//设置回调函数
		en.setCallback(this);
		//返回创建的子类(代理对象),因为cglib又被称为子类代理
		return en.create();
	}
	
	@Override
	public Object intercept(Object arg0, Method method, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		System.out.println("执行前");
		Object returnObj = method.invoke(obj, arg2);
		System.out.println("执行后");
		return returnObj;
	}
	
}

package study.proxy.Cglib;

public class CglibTest {
	
	public static void main(String[] args) {
		CglibClass cglib = new CglibClass();
		
		CglibClass proxy = (CglibClass)new CglibProxy(cglib).getProxyInstance();
		System.out.println(proxy);
		proxy.say();
		proxy.say1();
		proxy.say2();
	}
	
}

4.手写jdk动态代理

package study.proxy.JDKProxyRealization;
/**
 * 目标类要实现的接口
 * @author an
 *
 */
public interface JDKDemoInter {
	
	public void detailShow();
	
}
package study.proxy.JDKProxyRealization;
/**
 * 要被代理的类
 * 必须要有实现的接口
 * @author an
 *
 */
public class JDKClassDemo implements JDKDemoInter{
	
	private String name;
	
	public void detailShow(){
		System.out.println("你好我是JDKClassDemo");
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
	
}

package study.proxy.JDKProxyRealization;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

/**
 * 代理类的生成实例
 * @author an
 *
 */
public class ANProxy {

	private static final String TR = "\r\n";

	//产生代理对象
	public static Object getInstance(ANClassLoader classLoader,Class<?> [] interfaces,ANInvocationHandler h) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException{

		//生成源代码.java文件      添加实现interfaces接口的文件  并生成各个方法的代理类
		String javaStr = generateJavaString(interfaces);

		//java文件存储到磁盘
		String filePath = ANProxy.class.getResource("").getPath();
		File f = new File(filePath+"$Proxy0.java");
		try {
			FileWriter fw = new FileWriter(f);
			fw.write(javaStr);
			fw.flush();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		//把生成的.java文件编译成.class文件
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		StandardJavaFileManager manager = compiler.getStandardFileManager(null, null, null);
		Iterable iterable = manager.getJavaFileObjects(f);
		JavaCompiler.CompilationTask task = compiler.getTask(null, manager, null, null, null, iterable);
		task.call();
		try {
			manager.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		//编译生成的.class文件加载到jvm中来
		@SuppressWarnings("rawtypes")
		Constructor c =null;
		Class proxyClass = classLoader.findClass("$Proxy0");
		c = proxyClass.getConstructor(ANInvocationHandler.class);


		//删除.java文件
		//f.delete();

		//返回字节码重组以后的新的代理对象
		return c.newInstance(h);
		//return null;
	}

	private static String generateJavaString(Class<?>[] interfaces) {
		StringBuilder sb  = new StringBuilder();
		sb.append("package study.proxy.JDKProxyRealization;"+TR);
		sb.append("import study.proxy.JDKProxyRealization.JDKDemoInter;"+TR);
		sb.append("import java.lang.reflect.Method;"+TR);
		//暂时只实现第一个接口
		sb.append("public class $Proxy0 implements "+interfaces[0].getName()+" { "+TR);

		sb.append("ANInvocationHandler h;"+TR);

		sb.append("public $Proxy0 (ANInvocationHandler h){"+TR);
		sb.append(" this.h = h;"+TR);
		sb.append("}"+TR);

		for(Method m : interfaces[0].getMethods()){
			sb.append("public "+m.getReturnType().getName()+" "+m.getName() +"() { "+TR);
			sb.append("try {"+TR);
			sb.append("Method m ="+interfaces[0].getName()+".class.getMethod(\""+m.getName()+"\",new Class[]{});"+TR);
			sb.append("this.h.invoke(this,m,null);"+TR);
			sb.append("} catch (Throwable e) {"+TR);
			sb.append("e.printStackTrace();"+TR);
			sb.append("}"+TR);
			sb.append("}"+TR);
			sb.append("}"+TR);
		}

		return sb.toString();
	}

}

package study.proxy.JDKProxyRealization;

import java.lang.reflect.Method;

public interface ANInvocationHandler {
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

package study.proxy.JDKProxyRealization;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * 类加载
 * @author an
 *
 */
public class ANClassLoader extends ClassLoader{
	
	private File classPathFile;
	
	public  ANClassLoader(){
		String path = ANClassLoader.class.getResource("").getPath();
		this.classPathFile = new File(path);
	}

	@Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        String className = ANClassLoader.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(null != in){
                        try {
                            in.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }

                    if(out != null){
                        try {
                            out.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }

        }

        return null;

    }
	
	
}

package study.proxy.JDKProxyRealization;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * 代理类
 * @author an
 *
 */
public class AnProxyClass implements ANInvocationHandler{

	private JDKDemoInter obj;

	public Object getInstance(JDKDemoInter obj) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException{
		this.obj = obj;
		Class<?> clazz = obj.getClass(); 
		return ANProxy.getInstance(new ANClassLoader(), clazz.getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)  throws Throwable{

		System.out.println("代理前的操作");
		method.invoke(this.obj, args);
		System.out.println("代理后的操作");

		return null;
	}

}

package study.proxy.JDKProxyRealization;

import java.lang.reflect.InvocationTargetException;

public class AnProxyTest {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, NoSuchMethodException, SecurityException {
		JDKDemoInter ji = (JDKDemoInter)new AnProxyClass().getInstance(new JDKClassDemo());
		ji.detailShow();
	}
}





阅读更多
个人分类: 后端
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

静态代理和动态代理

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭