首页 > 编程语言 >Java后端06(代理模式)

Java后端06(代理模式)

时间:2023-08-07 16:45:56浏览次数:33  
标签:缓存 Java 后端 对象 代理 Rent 06 public rent

代理模式

​ spring 中就使用了代理模式,Java中的代理模式分为一下两种

  1. 静态代理:最简单,但是每次修改都需要重新编译
  2. 动态代理:分为两种(jdk 动态代理--通过接口实现来进行代理 & cglib 动态代理--通过子类继承来实现代理)

静态代理

​ 静态代理致命问题:代理对象必须提前编译好,所有代码都是写死固定的

举个栗子

// 用一个接口来表示出租的操作
public interface Rent {
    void rentSth();
}

// 定义一个房东类
public class Landlord implements Rent{
    // 房东有自己的房子,可以直接出租
    @Override
    public void rentSth() {
        rentHouse();
    }

    public void rentHouse(){
        System.out.println("landLord -> rentHouse()");
    }
}
// 定义一个中介,来代理房东
public class Intermediary implements Rent{
    // 中介本身是没有房子的,所以需要提供一个成员变量,用来存储其代理对象的内存地址
    // 被代理对象
    private Rent rent;
    // 构造方法传参
    public Intermediary(Rent rent){
        this.rent = rent;
    }
    // 实现房屋租赁
    @Override
    public void rentSth() {
        rent.rentSth();
        earnMoney();
    }

    public void earnMoney(){
        System.out.println("获得差价");
    }
}

测试类

// 调用中介的方法,租房东的房子,实现代理关系
public static void main(String[] args) {
    // 实例化房东
    Rent Landlord = new Landlord();
    // 实例化中介
    Rent intermediary = new Intermediary(Landlord);
    // 中介出租房屋
    intermediary.rentSth();
}

JDK动态代理

核心:被代理对象和代理对象共同实现一个接口,在对象调用方法的时候,使用代理对象偷偷替换掉被代理的对象,但是仍然使用父类引用

动态代理模式下,Rent接口是必须的,房东也是必须的,但是中介类不需要我们自己编写

​ 通过Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)自动帮我们实现代理

参数列表:

  1. loader:被代理对象的类加载器,如果我们写的时候正常的普通类,使用ClassLoader.getSystemClassLoader()方法获取类加载器
  2. interfaces:该参数表示的是被代理对象的接口的反射对象(class对象),因为可以代理多个类,所以需要使用数组引用进行传值
  3. InvocationHandler:行为处理器,虽然反射生成的代理对象(中介)可以代理被代理对象(房东)的所有行为,但是开发者需要告诉代理对象如何执行方法(动态代理生成的代理对象,会默认重写该对象的所有方法,使所有方法都只具有一个功能,即调用InvocationHandlerinvoke()方法)

invoke(Object proxy, Method method, Object[] args)方法:无论我门调用代理对象的哪一个方法,最终都会调用这个invoke()方法,进行行为处理

参数列表:

  1. proxy:代理对象自己,这个参数尽量不要使用,因为代理对象所有方法都会调用invoke(),最终会导致死递归调用
  2. method:因为无论调用代理对象的哪一个方法,最终都会调用invoke(),所以需要通过Method对象来识别,最终要调用的方法是哪一个
  3. args:参数,表示被代理对象所调用的方法的参数
  4. Object返回值:invoke()方法的返回值就是被代理对象调用方法的返回值
public static void main(String[] args) {
    // 使用动态代理模式来实现demo
    // 利用JDK动态代理,实例化一个代理对象
    Rent rent = (Rent) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Rent.class}, new InvocationHandler() {
        // 实例化被代理对象
        Rent rent = new Landlord();
        public void rested(){
            System.out.println("sb is rested!");
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            String methodName = method.getName();
            if(methodName.equals("rentSth")){
                rent.rentSth();
                rested();
            }
            return null;
        }
    });
    rent.rentSth();
}

Mybatis ---- pageHelper 分页插件

<!--添加配置文件-->
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
// 分页查询设置
PageHelper.offsetPage(1,2);

Mybatis ---- 一级缓存

​ mybatis中,只要通过一级缓存(sqlSession)查询的诗句,就会将数据存放在缓存中,下一次如果再查询相同的数据的时候,就不需要再从数据库获取,而是直接从缓存获取

⭐一级缓存失效的可能(数据不从缓存中获取,直接从数据库中获取):

  1. sqlSession不同
  2. sqlSession相同,但是查询条件不同(从缓存获取数据的前提,是缓存中得有对应的数据)
  3. sqlSession相同,两次查询之间执行了增删改查操作(增删改查操作可能会影响当前数据)
  4. sqlSession相同,开发者认为清除了一级缓存

Mybatis ---- 二级缓存

​ sqlSessionFactory 如果多次查询是基于同一个SqlSessionFactory创建的,就会从二级缓存中获取数据(前提是有数据)而不会从数据库中进行获取,二级缓存和一级缓存不同,并不是默认开启的,需要手动进行配置(配置配置文件 + cache标签)

1. MyBatis 配置文件中配置对应的二级缓存支持
1. 对应的 xml  中添加 `<cache/>`标签
1. ORM映射的实体类需要进行序列化支持`implements Serializable`
<!--支持二级缓存-->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

标签:缓存,Java,后端,对象,代理,Rent,06,public,rent
From: https://www.cnblogs.com/te9uila/p/17611813.html

相关文章

  • 深入探索JavaScript的魅力与奇妙之处
    大家好!今天我想分享一些关于JavaScript(简称JS)的思考和体会。作为前端开发中最重要的语言之一,JS不仅具备强大的功能,还有着许多令人着迷的特性。首先,JavaScript的灵活性是其最引人注目的特点之一。它允许我们以多种方式解决问题,无论是面向对象编程、函数式编程还是响应式编程,JS都能......
  • Java 远程连接 SQLite 数据库
    Java可以使用JDBCAPI来连接SQLite数据库。但是,SQLite不支持远程连接,因为它是一种文件数据库,需要直接访问数据库文件。如果您需要从远程位置访问SQLite数据库,可以将SQLite数据库文件放在共享文件夹中,并将该文件夹映射到本地计算机上。然后,您可以在本地计算机上使用JDBC......
  • 前后端滑块校验
    前端1.创建一个滑块组件slider点击查看代码<template><divclass="slider"><divclass="mask"><divclass="container"><divclass="title"><divclass="te......
  • Java设计模式的七大基本原则
    设计模式是为了让程序(软件)具有更好的代码重用性,可读性,可扩展性,可靠性,使程序呈现高内聚,低耦合的特性设计模式的原则其实就收是程序员在编写时,应当遵守的原则,也是各种模式的基础(Java设计模式的七大基本原则)一、单一职责原则<A>对类来说的,即一个类应只负责一项职责,如果A负责......
  • 【Java设计模式004】建造者模式
    大家好,个人gzh是大猪和小猪的小家,我们的gzh是朝阳三只大明白,满满全是干货,分享近期的学习知识以及个人总结(包括读研和IT),跪求一波关注,希望和大家一起努力、进步!!概述首先来看一个例子,假设我们需要建造一个房子,那么必须建造墙、屋顶、地板、门…如果还需要游泳池、健身室,那么该怎么办呢......
  • MySQL问题记录Can't connect to MySQL server on 'localhost' (10061)解决方法
    登录MySQL提示Can'tconnecttoMySQLserveron'localhost'(10061)进入安装目录bin目录,执行mysqld--install,启动MySQL点击查看代码cdD:\soft\MySQL\MySQLServer5.7\binmysqld--installnetstartmysql提示启动失败最后执行mysqld--initialize--user=root--......
  • Java 图片、文件 Base64 互转
    Java图片、文件Base64互转packagecom.thoth.his.base.util;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.IOException;importjava.util.Base64;publicclassImageUtil{publicStringFileToBase64(StringfilePath)thro......
  • 【转】JAVA中list和原生数组的互相转换
    经常用经常忘转自 javaList和数组相互转换的方法总结_javalist转为数组_great-sun的博客-CSDN博客Java中,可以通过以下方法将List转换为数组:List<String>list=newArrayList<>();String[]array=list.toArray(newString[0]);在这个例子中,我们将一个String类型的List......
  • java读写ini文件
    java读写ini文件1、格式INI文件由节、键、值组成。节[section]参数(键=值)name=value例:[Total]num=1[Server]ip=127.0.0.12、代码封装importorg.apache.commons.configuration.ConfigurationException;importorg.apache.commons.configuration.HierarchicalINIConfiguration;import......
  • java笔试常见的选择题(坑你没商量)
    java笔试常见的选择题(坑你没商量)1.已知表达式intm[]={0,1,2,3,4,5,6};下面那个表达式的值与数组的长度相等()Am.length()B.m.lengthC.m.length()+1D.m.length+1答案:B分析:数组的长度是.length2.下面那些声明是合法的?()Alongl=4990B.inti=4LC.floatf=1.1D.doubled......