• 代理模式-P19


    静态代理

    创建项目:

    Rent

    1. package com.Li.demo01;
    2. //租房
    3. public interface Rent {
    4. public void rent();
    5. }

     Proxy:

    1. package com.Li.demo01;
    2. //中介(负责找房东)
    3. public class Proxy implements Rent{
    4. //
    5. private Host host;
    6. public Proxy() {
    7. }
    8. public Proxy(Host host) {
    9. this.host = host;
    10. }
    11. @Override
    12. public void rent() {
    13. host.rent();
    14. }
    15. }

    Host:

    1. package com.Li.demo01;
    2. //房东
    3. public class Host implements Rent{
    4. @Override
    5. public void rent() {
    6. System.out.println("房东要出租房子!");
    7. }
    8. }

    Client:

    1. package com.Li.demo01;
    2. public class Client {
    3. public static void main(String[] args) {
    4. Host host = new Host();
    5. //代理
    6. Proxy proxy = new Proxy(host);
    7. proxy.rent();
    8. }
    9. }
    由于中介也需要房东,所以需要在此之前new一个房东。

    你可能认为有没有效果都一样,但是在这个过程中,中介可以有自己的属性和方法。增加自己想要的内容。

    修改之后

    Proxy:(增加了自己的特有方法)

    1. package com.Li.demo01;
    2. //中介(负责找房东)
    3. public class Proxy implements Rent{
    4. //
    5. private Host host;
    6. public Proxy() {
    7. }
    8. public Proxy(Host host) {
    9. this.host = host;
    10. }
    11. @Override
    12. public void rent() {
    13. seeHouse();
    14. host.rent();
    15. hetong();
    16. fare();
    17. }
    18. //看房
    19. public void seeHouse(){
    20. System.out.println("中介带你看房");
    21. }
    22. //签合同
    23. public void hetong(){
    24. System.out.println("签租赁合同");
    25. }
    26. //收费
    27. public void fare(){
    28. System.out.println("收中介费");
    29. }
    30. }

    此时就已经经过了中介之手,租到房了。

     


    拓展:

    新建demo02

    UserService:

    1. package com.Li.demo02;
    2. public interface UserService {
    3. public void add();
    4. public void delete();
    5. public void update();
    6. public void query();
    7. }

    UserServiceImpl:

    1. package com.Li.demo02;
    2. public class UserServiceImpl implements UserService{
    3. @Override
    4. public void add() {
    5. System.out.println("增加了一个用户");
    6. }
    7. @Override
    8. public void delete() {
    9. System.out.println("删除了一个用户");
    10. }
    11. @Override
    12. public void update() {
    13. System.out.println("修改了一个用户");
    14. }
    15. @Override
    16. public void query() {
    17. System.out.println("查询了一个用户");
    18. }
    19. }

    UserServiceProxy:(代理类)(重点!)========相当于复制了一份原本的内容,这样操作出错的时候也不会影响原本内容。

    1. package com.Li.demo02;
    2. public class UserServiceProxy implements UserService{
    3. //相当于在Proxy里面调取了UserServiceImpl
    4. private UserServiceImpl userService;
    5. public void setUserService(UserServiceImpl userService) {
    6. this.userService = userService;
    7. }
    8. @Override
    9. public void add() {
    10. log("add");
    11. userService.add();
    12. }
    13. @Override
    14. public void delete() {
    15. log("delete");
    16. userService.delete();
    17. }
    18. @Override
    19. public void update() {
    20. log("update");
    21. userService.update();
    22. }
    23. @Override
    24. public void query() {
    25. log("query");
    26. userService.query();
    27. }
    28. //日志方法
    29. public void log(String msg){
    30. System.out.println("[debug] 使用了"+msg+"方法");
    31. }
    32. }

    Client:(测试)

    1. package com.Li.demo02;
    2. public class Client {
    3. public static void main(String[] args) {
    4. UserServiceImpl userService = new UserServiceImpl();
    5. UserServiceProxy proxy = new UserServiceProxy();
    6. proxy.setUserService(userService);//中介(proxy)代理userService
    7. proxy.add();
    8. }
    9. }

    测试结果:

    AOP就是横切进去,用来完善之前的业务。

     


    动态代理:

    · 动态代理和静态代理角色一样
    · 动态代理的代理类是动态生成的,不是我们直接写好的!
    · 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
            ·基于接口 — JDK动态代理【我们在这里使用】
            ·基于类:cglib
            ·java字节码实现:javassist
    需要了解两个类:Proxy:代理;InvocationHandler:调用处理程序。

    Rent(接口)

    1. package com.Li.demo03;
    2. //租房
    3. public interface Rent {
    4. public void rent();
    5. }
    Host
    
    1. package com.Li.demo03;
    2. //房东
    3. public class Host implements Rent {
    4. @Override
    5. public void rent() {
    6. System.out.println("房东要出租房子!");
    7. }
    8. }

    ProxyInvocationHandler(核心)(就相当于中介)

    1. package com.Li.demo03;
    2. import java.lang.reflect.InvocationHandler;
    3. import java.lang.reflect.Method;
    4. import java.lang.reflect.Proxy;
    5. //等会我们会用这个类,自动生成代理类!
    6. public class ProxyInvocationHandler implements InvocationHandler {
    7. //被代理的接口
    8. private Rent rent;
    9. public void setRent(Rent rent) {
    10. this.rent = rent;
    11. }
    12. //生成得到代理类
    13. //(返回三个参数:用哪个类加载器去加载代理对象(中介),被代理的对象(房东),谁来进行这种new操作(运用invoke来操作)生成中介(也就是谁来生成中介))
    14. //通过本程序的类加载器,来加载需要被代理的角色,生成代理类(三个参数的解释)
    15. //一般只需要修改中间的参数就可以了
    16. public Object getProxy(){
    17. return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
    18. }
    19. //处理代理实例,并返回结果(真正的中介,上面的中介相当于是复制之前的内容,这个相当于可以在复制内容上面修改)
    20. @Override
    21. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    22. seeHouse();
    23. //动态代理的本质,就是使用反射机制实现!
    24. Object invoke = method.invoke(rent, args);
    25. fare();
    26. return invoke;
    27. }
    28. public void seeHouse(){
    29. System.out.println("中介看房子");
    30. }
    31. public void fare(){
    32. System.out.println("收中介费");
    33. }
    34. }

    Client:(测试)

    1. package com.Li.demo03;
    2. public class Client {
    3. public static void main(String[] args) {
    4. //真实角色
    5. Host host = new Host();
    6. //代理角色:现在没有,但是有可以生成代理类的东西
    7. ProxyInvocationHandler pih = new ProxyInvocationHandler();
    8. pih.setRent(host);
    9. //生成代理类
    10. Rent proxy = (Rent) pih.getProxy();
    11. proxy.rent();
    12. }
    13. }

     

  • 相关阅读:
    vue3使用view-ui定制主题
    云原生容器技术入门:Docker、K8s技术的基本原理和用途
    如何使用postman调用若依系统接口(报错401,认证失败,无法访问系统资源)
    LaTeX中的积分符号
    阿龙的感悟
    数据结构--第七天
    Android开发 -- MPAndroidChart动态刷新和清除数据点
    使用Bochs调试操作系统代码
    Flutter开发实战之Google Play 最佳应用程序开发者分享Flutter经验与技巧
    golang设计模式——享元模式
  • 原文地址:https://blog.csdn.net/m0_54842832/article/details/127974527