国内网站建设最好公司,3合1网站建设,企业常用邮箱,创意设计产业包括哪些代理模式
为什么要学习代理模式#xff1f;因为这是SpringAOP的底层#xff01; 【SpringAOP和SpingMVC}】
代理模式的分类#xff1a; 静态代理 动态代理
代理就像这里的中介#xff0c;帮助你去做向房东租房#xff0c;你不能直接解出房东#xff0c;而房东和中介…代理模式
为什么要学习代理模式因为这是SpringAOP的底层 【SpringAOP和SpingMVC}】
代理模式的分类 静态代理 动态代理
代理就像这里的中介帮助你去做向房东租房你不能直接解出房东而房东和中介是因为租房而联系在一起所以租房是接口 静态代理
角色分析
抽象角色(租房)一般使用接口和抽象类来解决真实角色(房东)被代理的角色代理角色(中介)代理真实角色被代理真实角色后我们一般会做一些附属工作客户访问代理对象的人
代码步骤 接口 package com.hong;//租房
public interface Rent {public void rent();
} 真实角色 package com.hong;public class Client {public static void main(String[] args) {//房东要租房子Host host new Host();//代理中介帮房东租房子但是呢房东会加一些附属操作!
// host.rent();Proxy proxy new Proxy(host);//你不用面对房东直接找中介即可proxy.rent();}
} 代理角色 package com.hong;public class Proxy implements Rent{private Host host;public Proxy(Host host) {this.host host;}public Proxy() {}Overridepublic void rent() {host.rent();seeHost();fare();hetong();}//看房public void seeHost(){System.out.println(中介带你看房);}public void hetong(){System.out.println(签合同);}//收中介费public void fare(){System.out.println(收中介费);}
} 客户端访问代理角色 package com.hong;//房东
public class Host implements Rent{Overridepublic void rent() {System.out.println(房东要出租房子);}
}
代理模式的好处
可以使真实角色的操作更加纯粹!不用去关注一些公共的业务公共也就就交给代理角色!实现了业务的分工!公共业务发生扩展的时候方便集中管理!
缺点
一个真实角色就会产生一个代理角色;代码量会翻倍开发效率会变低
AOP
用代理增加功能不改动原有的代码只改动代理类
package com.hong;//真实对象
public class UserServiceImpl implements UserService {Overridepublic void add() {System.out.println(增加一个用户);}Overridepublic void delete() {System.out.println(删除一个用户);}Overridepublic void update() {System.out.println(修改了一个用户);}Overridepublic void query() {System.out.println(查询了一个用户);}
}
package com.hong;public class UserServiceProxy implements UserService{private UserServiceImpl userservice;public void setUserservice(UserServiceImpl userservice) {this.userservice userservice;}Overridepublic void add() {log(add);userservice.add();}Overridepublic void delete() {log(delete);userservice.delete();}Overridepublic void update() {}Overridepublic void query() {}public void log(String msg){System.out.println(调用msg方法);}
}
package com.hong;public interface UserService {public void add();public void delete();public void update();public void query();
}
package com.hong;public class Client {public static void main(String[] args) {UserServiceImpl userService new UserServiceImpl();UserServiceProxy proxy new UserServiceProxy();proxy.setUserservice(userService);proxy.add();}
} 动态代理
动态代理和静态代理角色一样动态代理类是动态生成的不是我们直接写好的动态代理分为两大类基于接口的动态代理基于类的动态代理 基于接口—JDK动态代理基于类cglibjava字节码实现javasist
需要了解两个类proxy代理lnvocationHandler调用处理程序
静态代理的好处
可以使真实角色的操作更加纯粹!不用去关注一些公共的业务公共也就就交给代理角色!实现了业务的分工!公共业务发生扩展的时候方便集中管理!一个动态代理类代理的是一个接口一般就是对应的一类业务一个动态代理修改的成本极低
实现代码
动态代理
package com.hong.demo02;import com.hong.xxh.Rent;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;//自动生成代理
public class ProxyInvocationHandler implements InvocationHandler {//被代理的接口private Object taget;public void setTaget(Object taget) {this.taget taget;}//生成得到代理对象public Object getProxy() {return Proxy.newProxyInstance(this.getClass().getClassLoader(),taget.getClass().getInterfaces(),this);}//处理代理实例并返回结果public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {Object result method.invoke(taget, args);return result;}
}
接口
package com.hong.demo02;public interface UserService {public void add();public void delete();public void update();public void query();
}真实对象
package com.hong.demo02;//真实对象
public class UserServiceImpl implements UserService {Overridepublic void add() {System.out.println(增加一个用户);}Overridepublic void delete() {System.out.println(删除一个用户);}Overridepublic void update() {System.out.println(修改了一个用户);}Overridepublic void query() {System.out.println(查询了一个用户);}
}
客户端访问
package com.hong.demo02;import com.hong.Proxy;
import com.hong.UserServiceImpl;public class ClenClient {public static void main(String[] args) {//真实角色UserServiceImpl userService new UserServiceImpl();//代理角色ProxyInvocationHandler pih new ProxyInvocationHandler();pih.setTaget(userService); //设置要代理的对象//动态生成代理UserService proxy (UserService) pih.getProxy();proxy.delete();}
}
反序列化中动态代理的利用
我们将入口类定义为A我们最理想的情况是 A[O] - O.f那么我们将传进去的参数O替换为B即可。但是在实战的情况下这种情况是极少的。
回到实战情况比如我们的入口类A存在O.abc这个方法也就是 A[O] - O.abc而 O 呢如果是一个动态代理类O的invoke方法里存在.f的方法便可以漏洞利用了我们还是展示一下。 A[O] - O.abc O[O2] invoke - O2.f // 此时将 B 去替换 O2 最后 ---- O[B] invoke - B.f // 达到漏洞利用效果 就像readObject在反序列化中自动调用invoke在动态代理的时候也自动调用如果我们在invoke插入恶意代码就可进行攻击例如 结果