java 静态代理与jdk动态代理

1.java动态代理出现的前因

 众所周知,java是一个混合型语言,既是编译型又是解释型语言。.java文件通过编译器编译生成.clss字节码文件,在安装有JVM平台上解释运行.class文件。
 所以java的语言特点就是,程序员写出来.java类->.class->运行,一旦程序代码类提交后编译成.class文件,就不能修改。
 动态代理就是为了解决不能扩展修改的问题。学习动态代理前先理解代理的概念。

2.代理类-代理模式

代理模式是常用的设计模式之一,特征是代理类和被代理类有同一个接口类 。
代理模式提供了访问实际对象的中间层,通过调用代理类访问被代理类,例子来源于https://www.cnblogs.com/gonjan-blog/p/6685611.html。

在这里插入图片描述

3.静态代理

静态代理:程序员写的代理类或者特定的工具自动生成的源代码,在程序编译成.class文件后不能对其修改。

//接口
public interface Person {
	//静态代理类需要先有接口
	void giveMoney();
}
//被代理类,也是真正访问的类,和代理类一样,只实现同一个接口
public class Student implements Person {
	private String name;
	public Student(String name) {
		super();
		this.name = name;
	}
	@Override
	public void giveMoney() {
		// TODO Auto-generated method stub
		System.out.println(name+"上交班费50元");
	}
}
//代理类,和被代理类一样,只实现同一个接口
public class StudentsProxy implements Person {
	Student stu;
	public StudentsProxy(Person stu) {
		if(stu.getClass()==Student.class) {
			this.stu = (Student) stu;
		}	
	}
	@Override
	public void giveMoney() {
		// TODO Auto-generated method stub
		//预处理或者扩展的方法
		beforeMethod();
		//代理类中,闯将被代理类对象后,调用被代理类的方法
		stu.giveMoney();
	}
	//原来实现接口还能在实现接口的类里添加其他方法啊
	void beforeMethod(){
		System.out.println("无java经验找不着工作?");
	}
}
import staticproxy.Person;
import staticproxy.Student;
import staticproxy.StudentsProxy;
public class StaticProxyTest {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建被代理的对象,多态的扩展
		Person student=new Student("皮皮");
		//创建代理对象
		Person studentProxy= new StudentsProxy(student);
		studentProxy.giveMoney();
	}
}

4.动态代理

动态代理是为了解决系统在运行时不能修改扩展的问题,在运行的状态下利用java反射机制动态生成 比如,下午完整的例子。
第一步,创建代理模式的接口Person
第二步,创建核心类,也就是被代理类Studentd
第三步,实现InvocationHandler 接口类创建StuInvocationHandler
第四步,调用过程中,创建一个代理对象stuProxy 来代替zhangsan,然后使用proxy类动态创建代理类。

//接口,代理模式都需要的接口
public interface Person {
	//静态代理类需要先有接口
	void giveMoney();
}
//创建要被代理的类
import staticproxy.Person;
public class Studentd implements Person {
	String name;
	public Studentd(String name) {
		// TODO Auto-generated constructor stub
		this.name = name;
	}
	@Override
	public void giveMoney() {
		// TODO Auto-generated method stub
		try {
			Thread.sleep(5000);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		System.out.println(name+"上交班费50元");
	}
}
package dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class StuInvocationHandler implements InvocationHandler {
	//target是StuInvocationHandler所持有的被代理对象
	Object target;
	public StuInvocationHandler(Object target) {
		super();
		this.target = target;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] arg2) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("代理执行"+method.getName()+"方法");
		//拓展的方法
		//MonitorUntil
		MonitorUntil.start();
		Object result= method.invoke(target, arg2);
		MonitorUntil.finish(method.getName());
		return result;
	}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import dynamicproxy.StuInvocationHandler;
import dynamicproxy.Studentd;
import staticproxy.Person;
public class DynamicProxyTest {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//创建被代理的实例对象
		Person zhangsan = new Studentd("皮皮");
		//创建与代理对象相关联的InvocationHandler
		InvocationHandler stuHandler= new StuInvocationHandler(zhangsan);
		/*
		 * Person:自创接口类
		 * 
		 * stuHandler:自创InvocationHandler
		 * 
		 * 创建一个代理对象stuProxy 来代替zhangsan,代理对象的每个方法都会替换执行 StuInvocationHandler 中的方法
		 * Proxy提供了用于创建动态代理类和实例的静态方法,它也是由这些方法创建的所有动态代理类的超类。
		 *   * */
		Person stuProxy =(Person) Proxy.newProxyInstance(Person.class.getClassLoader(),new Class<?>[] {Person.class} , stuHandler);
		stuProxy.giveMoney();
	}
}

结果是:在这里插入图片描述

5.动态代理和静态代理

当我们应用时jdk动态代理和静态代理区别在哪儿?

动态代理静态代理

1 jdk动态代理是在程序运行时,通过java的反射机制动态创建代理类,无需程序员手动编写它的代理类。


2 jdk动态代理一次可代理同一个接口下多个实现类。


3 jdk动态代理在运行前,不知道它所代理什么类。

1 代理类由程序员手动创建或者由特定工具自动生成源码,对源码编译后,在运行前就已经有.class代码。


2 静态代理只能代理一个类。

3 静态代理事先知道要代理哪个类

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值