知识点:静态代理和动态代理html
参考博客:https://www.cnblogs.com/daniels/p/8242592.html缓存
https://blog.csdn.net/familyshizhouna/article/details/78905997less
一:什么是代理模式ide
代理模式是给某个对象提供一个代理对象,由代理对象调用原对象的方法,相似咱们生活中的中介,经纪人的角色,本人不直接去作,找一我的代替咱们去作一些事情。测试
二:使用代理模式的好处this
a.中介隔离做用:当咱们不想直接调用一个对象时,代理对象能够起一个中介隔离的做用,被代理对象和代理对象都实现相同的接口spa
b.遵循开闭原则:咱们能够经过代理类,在被代理类功能先后,加入一些公共服务,好比缓存,日志等,而不用修改原被代理类.net
三:代理模式的分类代理
按建立代理的时间分类能够分为:静态代理和动态代理日志
静态代理是代码建立后编译,运行以前,代理类的.class文件就已经建立了;
动态代理:是在程序运行时,经过反射机制动态建立代理对象的(另外一篇博客简略地介绍Java中的反射:https://www.cnblogs.com/shuaifing/p/10863645.html)
(1)静态代理
//代理模式(静态代理)
//测试类
public class StaticProxy {
public static void main(String[] args) {
Object obj=new ProxyObject();
obj.action();
}
}
//公共接口
interface Object{
void action();
}
//代理类
class ProxyObject implements Object{
Object obj;
public ProxyObject(){
System.out.println("代理类构造方法建立被代理类");
obj=new ObjectImp();
}
@Override
public void action() {
System.out.println("代理类执行被代理类中的方法");
obj.action();
}
}
//被代理类
class ObjectImp implements Object{
@Override
public void action() {
System.out.println("被代理类输出的内容!");
}
}
运行结果:

(2)动态代理
当有多个类要代理的话,手动建立多个代理对象比较麻烦,代码冗余,动态产生代理对象的话,代码更加灵活,方便
//动态代理,反射是动态语言的关键
//测试类
public class DynamicProxy {
public static void main(String[] args) {
//1.被代理类的对象
RealSubject realSubject=new RealSubject();
//2.建立一个实现InvocationHandler接口类的对象
MyInvocationHandler handler=new MyInvocationHandler();
//3.调用blind()方法,动态返回一个实现了跟被代理类所实现接口的代理对象
Object obj=handler.blind(realSubject);
Subject subject=(Subject) obj;//subject是代理类对象
subject.action();//代理类对象调用action(),会转到对InvocationHandler接口实现类的invoke()方法调用
//增长另外一个 ObjectImp的被代理对象,返回相应的代理对象
ObjectImp objIml=new ObjectImp();
com.kdgc.interfacetest.Object proxyObject= (com.kdgc.interfacetest.Object)handler.blind(objIml);
proxyObject.action();
}
}
//公共接口
interface Subject{
void action();
}
//被代理类
class RealSubject implements Subject{
@Override
public void action() {
System.out.println("被代理类要执行的方法!");
}
}
class MyInvocationHandler implements InvocationHandler{
Object obj;//实现了接口的被代理对象的声明
//1.给被代理对象实例化 2.返回一个代理类的对象
public Object blind(Object obj){
this.obj=obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
}
//当经过代理类的对象发起对被重写方法的调用时,会转化为对下面的invoke方法的调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object val=method.invoke(obj,args);
return val;
}
}
运行结果:

(3)补充:动态代理与AOP
在固定的代码的位置,动态地调用不一样对象的方法
//测试类
public class AOPTest {
public static void main(String[] args) {
Man man = new Man();
Person person = (Person) MyProxy.getProxyInstance(man);
person.drink();
person.eat();
}
}
//公共接口
interface Person{
void eat();
void drink();
}
//被代理类
class Man implements Person{
@Override
public void eat() {
System.out.println("吃东西!");
}
@Override
public void drink() {
System.out.println("喝水!");
}
}
//固定的方法
class ChangelessMethodUtil{
public void method1(){
System.out.println("===========方法1==========");
}
public void method2(){
System.out.println("============方法2===========");
}
}
class MyInvocationHanlder implements InvocationHandler{
Object obj;//代理类的声明
public void setObject(Object obj){
this.obj=obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
ChangelessMethodUtil changelessMethodUtil=new ChangelessMethodUtil();
changelessMethodUtil.method1();
method.invoke(obj,args);
changelessMethodUtil.method2();
return null;
}
}
class MyProxy{
//动态建立一个代理类的对象
public static Object getProxyInstance(Object obj){
MyInvocationHanlder hanlder=new MyInvocationHanlder();
hanlder.setObject(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),hanlder);
}
}
运行结果: