三级缓存

【白话Spring】三级缓存 容器只是个工具,怎么用才是我们需要了解的关键,什么时候给容器里存入Bean,把Bean存入哪个容器,什么时候清空容器,这就不得不了解一下Spring中Bean的生命周期了。设想一下没有三级缓存的循环依赖问题:ServiceA依赖ServiceB,ServiceB依赖ServiceA。每次获取到的都是新的代理对象,就破坏了Spring解决循环依赖问题的基础,即所有的对象都是单例的。解决循环依赖的问题有两级缓存就够了,为什么要用三级缓存呢?从上面的代码中可以看出,三级缓存就是3个全局的Map。 阅读详情

本文章可以学到:

1、图片压缩

2、图片异步加载

3、内存缓存

4、本地缓存

5、网络缓存

6、MD5加密


代码下载:http://download.youkuaiyun.com/detail/runingling/9674550


<strong>MyBitmapUtils //工具集</strong>

package com.example.liangshaoteng.mycache.Utils;

import android.graphics.Bitmap;
import android.util.Log;
import android.widget.ImageView;

import com.example.liangshaoteng.mycache.R;

/**
 * Created by LiangShaoTeng on 2016/10/26.
 */

public class MyBitmapUtils {

    private final MemoryCacheUtils memoryCacheUtils;
    private final LocalCacheUtils localCacheUtils;
    private final NetCacheUtils netCacheUtils;
    private Bitmap bitmap;

    public MyBitmapUtils() {
        //内存
        memoryCacheUtils = new MemoryCacheUtils();
        //本地
        localCacheUtils = new LocalCacheUtils();
        //网络
        netCacheUtils = new NetCacheUtils(memoryCacheUtils,localCacheUtils);
    }

    public void disPlay(ImageView imageView,String url){

        imageView.setImageResource(R.mipmap.ic_launcher);


        //内存缓存
        bitmap = memoryCacheUtils.getImageBitmapMemory(url);
        if(bitmap !=null){
            imageView.setImageBitmap(bitmap);

            System.out.println("从内存获取图片");
            return;
        }



        //本地缓存
        bitmap = localCacheUtils.getImageBitmapLocal(url);
        if(bitmap !=null){
            imageView.setImageBitmap(bitmap);
            //从本地获取图片存入内存
            memoryCacheUtils.setBitmapToMemory(url, bitmap);

            System.out.println("从本地获取图片");
            return;
        }


        //网络存储
        netCacheUtils.getBitmapRequest(imageView,url);

    }
}


<strong>MemoryCacheUtils //内存缓存</strong>


package com.example.liangshaoteng.mycache.Utils;

import android.graphics.Bitmap;
import android.os.Environment;
import android.util.LruCache;

/**
 * Created by LiangShaoTeng on 2016/10/26.
 */

public class MemoryCacheUtils {

    private final LruCache<String, Bitmap> mMemoryCache;

    public MemoryCacheUtils() {
        //获取手机允许最大内存的1/8,如果超过指定内存,就开始回收
        long maxMemory = Runtime.getRuntime().maxMemory() / 8;
        //需要传入允许的内存最大值,虚拟机默认内存16M,真机不一定相同
        mMemoryCache = new LruCache<String, Bitmap>((int) maxMemory) {
            @Override
            protected int sizeOf(String key, Bitmap value) {
                //获取对象的大小
                int byteCount = value.getByteCount();
                return byteCount;
            }
        };


    }

    public Bitmap getImageBitmapMemory(String url) {
        //通过url的key值查找图片
        try {
            String encode = MD5Encoder.encode(url);
            Bitmap bitmap = mMemoryCache.get(encode);
            return bitmap;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    public void setBitmapToMemory(String url, Bitmap bitmap) {
        try {
            String encode = MD5Encoder.encode(url);
            mMemoryCache.put(encode, bitmap);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}


<strong>LocalCacheUtils //本地缓存</strong>



package com.example.liangshaoteng.mycache.Utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilterInputStream;

/**
 * Created by LiangShaoTeng on 2016/10/26.
 */

public class LocalCacheUtils {

    private static final String CACHE_PATH=Environment.getExternalStorageDirectory().getAbsolutePath()+"/cache";

    public Bitmap getImageBitmapLocal(String url) {

        try {
            String encode = MD5Encoder.encode(url);

            File file=new File(CACHE_PATH,encode);

            //decodeStream 解码输入流的位图
            //FileInputStream 用于读取本地文件中的字节数据,继承自InputStream类
            Bitmap bitmap= BitmapFactory.decodeStream(new FileInputStream(file));
            return bitmap;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public void setBitmapToLocal(String url,Bitmap bitmap){

        try {
            String encode = MD5Encoder.encode(url);
            File file=new File(CACHE_PATH,encode);

            File parentFile = file.getParentFile();
            if(!parentFile.exists()){
                parentFile.mkdir();
            }

            //bitmap.compress(CompressFormat,quality,)
            //CompressFormat 压缩格式
            bitmap.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}


<strong>NetCacheUtils //网络缓存</strong>



package com.example.liangshaoteng.mycache.Utils;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.widget.ImageView;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

/**
 * Created by LiangShaoTeng on 2016/10/26.
 */

public class NetCacheUtils {
    MemoryCacheUtils memoryCacheUtils;
    LocalCacheUtils localCacheUtils;
    private HttpURLConnection urlConnection;

    public NetCacheUtils(MemoryCacheUtils memoryCacheUtils, LocalCacheUtils localCacheUtils) {
        this.localCacheUtils=localCacheUtils;
        this.memoryCacheUtils=memoryCacheUtils;
    }

    public void getBitmapRequest(ImageView imageView, String url) {
        new BitmapTask().execute(imageView,url);

    }

    class BitmapTask extends AsyncTask<Object,Void,Bitmap>{

        private ImageView imageView;
        private String url;

        @Override
        protected Bitmap doInBackground(Object... objects) {
            imageView = (ImageView) objects[0];
            url =  (String) objects[1];
            return downLoadBitmap(url);
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if(bitmap!=null){
                imageView.setImageBitmap(bitmap);

                System.out.println("从網絡获取图片");
                //存入内存
                memoryCacheUtils.setBitmapToMemory(url,bitmap);
                //存入本地
                localCacheUtils.setBitmapToLocal(url,bitmap);
            }

            super.onPostExecute(bitmap);
        }
    }

    private Bitmap downLoadBitmap(String url) {
        try {
            urlConnection = (HttpURLConnection) new URL(url).openConnection();
            urlConnection.setRequestMethod("GET");

            if(urlConnection.getResponseCode()== HttpURLConnection.HTTP_OK){

                BitmapFactory.Options bitmapFactory=new BitmapFactory.Options();
                bitmapFactory.inSampleSize = 2;//宽高压缩为原来的1/2
                bitmapFactory.inPreferredConfig= Bitmap.Config.ARGB_4444;
                /*Rect rect=new Rect();
                rect.contains(5,500,5,5);*/
                Bitmap bimap=BitmapFactory.decodeStream(urlConnection.getInputStream(),null ,bitmapFactory);
                return bimap;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            urlConnection.disconnect();
        }

        return null;
    }

}

<strong>MD5Encoder //MD5</strong>



package com.example.liangshaoteng.mycache.Utils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by LiangShaoTeng on 2016/10/26.
 */

public class MD5Encoder {
    public static String encode(String string) throws Exception {
        byte[] hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10) {
                hex.append("0");
            }
            hex.append(Integer.toHexString(b & 0xFF));
        }
        return hex.toString();
    }
}



Python爬虫实战:使用最新技术抓取采购网招标公告信息 本文将详细介绍如何使用Python最新爬虫技术构建一个高效的采购网招标公告信息抓取系统。我们将从爬虫基础概念讲起,逐步深入到高级技巧,包括异步处理、反爬虫对策、数据解析与存储等,并提供完整的代码实现。本文旨在为读者提供一套完整的网络数据采集解决方案,适用于各类政府采购平台和商业招标网站。网络爬虫(Web Crawler)是一种自动抓取互联网信息的程序或脚本,它们按照一定的规则,自动地浏览万维网并提取所需数据。在现代商业环境中,爬虫技术广泛应用于价格监控、竞争情报收集、市场研究等领域。 阅读详情

相关推荐

别再只调PID了!手把手教你从LC谐振到检波,搞定STM32智能车电磁循迹硬件电路

本文深入解析STM32智能车电磁循迹硬件电路设计,从LC谐振选频到数字信号处理,提供完整的信号链路设计要点与实战技巧。通过优化电磁杆布局和信号放大电路,显著提升赛道位置检测精度,误差可控制在±0.5cm以内,为智能车竞赛提供可靠硬件支持。

weixin_29220405的博客 263

三级缓存的理解

三级缓存的理解

beiback的博客 4101

STM32duino LSM6DSO驱动库:低功耗IMU工程化实践

惯性测量单元(IMU)是智能终端与工业设备实现运动感知的核心传感器,其性能关键在于数据精度、实时响应与系统功耗的协同优化。LSM6DSO作为集成加速度计与陀螺仪的六轴MEMS器件,依托片上有限状态机(FSM)和机器学习核心(MLC),支持自由落体检测、计步器、6D方向识别等硬件自治功能,显著降低主控CPU负载。在STM32平台下,通过深度耦合HAL/LL库、显式引脚管理、DMA加速SPI传输及EXTI中断协同,可实现亚毫秒级事件响应与微安级待机功耗。本文聚焦STM32duino生态中LSM6DSO驱动的工程

weixin_36304957的博客 551

CPU 与 内存之间的三级缓存的实现原理

一. CPU 与 Memory 内存之间的三级缓存的实现原理 1.1 cache 存在的原理   引入 Cache 的理论基础是程序局部性原理,包括时间局部性和空间局部性。时间局部性原理即最近被CPU访问的数据,短期内CPU 还要访问(时间);空间局部性即被CPU访问的数据附近的数据,CPU短期内还要访问(空间)。因此如果将刚刚访问过的数据缓存在一个速度比主存快得多的存储中,那下次访问时,可以直接从这个存储中取,其速度可以得到数量级的提高。   CPU缓存是(Cache Memory)位于CPU与内存

首席技术总监的专栏 8907

统信UOS安装CH384串口卡驱动

本文讲解如何在统信UOS系统下安装CH384 PCIE多串口驱动安装过程,CPU为飞腾D2000。其他Linux内核系统安装亦可参照类似方法。

shjhuang的专栏 1884

关于Kswapd的理解(一)

关于Kswapd的理解(一) 之前跟踪了MemAvailable的计算方式,其中watermark的计算花了很多精力,在学习的过程中看到一些资料中说watermark是给swapd使用的,于是乎,研究一下看看咯 本部分主要记录两个方面: 对于kswapd这个东西,从初学者(我)的角度出发会考虑哪些内容? 跟踪kswapd 初始化结构部分; 1. KSwapd机制 上图是还没有跟踪kswapd code的时候,对自己提出的一些疑问和自身的理解,主要是如下内容: kswapd 机制用来做什么:内存不足时

And乔的博客 2715

java 三级缓存

就是把访问量较高的热点数据从传统的关系型数据库中加载到内存中,当用户再次访问热点数据时是从内存中加载,减少了对数据库的访问量,解决了高并发场景下容易造成数据库宕机的问题。

林在闪闪发光的博客 3610

企业微信/飞书/钉钉扫码连WiFi保姆级教程(附访客授权技巧)

本文提供了一份企业微信、飞书、钉钉扫码连接WiFi的实战部署教程。通过集成标准Radius协议与OAuth 2.0,企业可实现基于身份的无密码网络认证,并详细介绍了访客授权、权限分级等精细化管理技巧,有效提升无线网络的安全性与员工体验。

t4y5u6i7o的博客 1194

Spring--三级缓存机制

/ 一级缓存Map 存放完整的Bean(流程跑完的)// 二级缓存Map 存放不完整的Bean(只实例化完,还没属性赋值、初始化)// 三级缓存Map 存放一个Bean的lambda表达式(也是刚实例化完)用来解决什么问题?这个大家应该熟知了,就是循环依赖什么是循环依赖?就像下面这样,AService 中注入了BService ,而BService 中又注入了AService ,这就是循环依赖@Service@Resource@Service@Resource。

gghhb12的博客 7143

【深度学习新浪潮】如何上手DINO v3:Meta新一代视觉大模型实战指南

自定义数据集类(适配本地/公开数据集)# 去除batch维度# 构建数据加载器# 定义分类模型(冻结预训练层,仅训练分类头)self.classifier = nn.Linear(dino_model.config.hidden_size, num_classes) # 分类头global_feat = outputs.global_attention_pool # 取全局特征# 初始化模型# 冻结预训练层(仅训练分类头)# 定义损失函数和优化器。

专注:太空算力、AI infra、异构调度、大模型成本工程 491

【ESP32使用MAX98357播放音频】

在物联网和智能家居领域,音频播放功能越来越受到重视。ESP32作为一款功能强大的微控制器,结合MAX98357音频放大器模块,可以实现高品质的音频播放。本文将详细介绍如何使用ESP32的I2S接口通过MAX98357进行音频播放。

vor234的博客 7529

MyBatis的三级缓存

关于MyBatis三级缓存的技术文章,从一级缓存到二级缓存,再到三级缓存,详细分析了它们的实现方式和使用场景,对于理解MyBatis提供的缓存机制有较大的帮助。同时,文章也给出了相应的示例代码和测试用例,以便读者更好地理解和使用MyBatis的缓存机制。

王德昌的博客 3662

麻雀搜索算法(SSA)详解:从鸟群智能到优化实践

麻雀搜索算法(SSA)是一种新型群智能优化算法,模拟麻雀群体的觅食行为和反捕食机制。该算法将优化问题转化为麻雀群体对食物源的搜索过程,通过发现者、加入者和警戒者的角色分工实现高效优化。SSA具有原理新颖、参数合理、收敛快速等特点,在函数优化、工程设计和机器学习等领域展现出良好应用前景。算法通过数学模型模拟麻雀的觅食策略,包括发现者全局探索、加入者局部开发和警戒者危险预警机制,有效平衡了全局搜索与局部开发能力。SSA相比传统优化算法具有更好的收敛性和优化效果。

qq_42212808的博客 1072

Spring的三级缓存

初始化对象 是否可以没有二级缓存 是否需要三级缓存 主要参考以下几篇文章做了简单的总结:一文告诉你Spring是如何利用"三级缓存"巧妙解决Bean的循环依赖问题的Spring循环依赖三级缓存是否可以去掉第三级缓存spring:我是如何解决循环依赖的?Spring 解决循环依赖为什么使用三级缓存,而不是二级缓存...

m0_67401417的博客 2万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Spring三级缓存详解

Spring三级缓存是为了解决对象间的循环依赖问题。

WorldMvp的专栏 1万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Spring三级缓存

什么是spring的循环依赖?spring容器的bean互相依赖形成闭环,称为spring的循环依赖。spring循环依赖只能用于set方法和成员变量注入实现,且要求是单例bean,多例(原型bean)是不能实现循环依赖的。构造方法注入是不能实现循环依赖的,会抛出异常(Requested bean is currently in creation: Is there an unresolvable circular reference?...

qq_36363499的博客 1万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Spring 三级缓存

spring三级缓存常见问题解析

tszc95的博客 3489

Spring 的三级缓存机制

这时,bean B 也需要依赖 bean A,但由于 bean A 的工厂对象已经在三级缓存中,Spring 可以直接从三级缓存中获取到 bean A 的工厂对象,并通过它来创建 bean A 的实例。而对于需要被AOP代理的Bean,singletonFactories中的工厂对象会先创建一个原始的Bean实例,然后通过AOP代理来生成代理对象,并将代理对象放入一级缓存singletonObjects中。:在Spring中,AOP代理是在Bean的初始化阶段完成的,这意味着所有的属性填充和方法调用之后。

m0_51431003的博客 6147

Spring的三级缓存及其原因

首先看下Spring创建一个bean的基本流程: 创建该实例的原始对象 --> 进行自动装配 --> AOP代理处理 --> 完成bean的创建并加入单例池(即一级缓存) 但是当有循环依赖的时候,Spring是如何解决的呢? 主要原理是利用三级缓存机制: singletonObjects: 一级缓存,也就是我们平常理解的单例池。 singletonFactories: 二级缓存,存储的是单例工厂。 earlySingletonObjects: 三级缓存,存储正在创建中的单例对象。

Mr_Gu的博客 9108

三级缓存架构

三级缓存架构是一种通过分层缓存设计来优化系统性能、降低数据库负载、提高数据访问效率的解决方案,尤其适用于高并发、高吞吐量的业务场景(如电商、社交平台、实时推荐等)。其核心思想是通过多级缓存逐层过滤请求,减少对底层存储的直接访问。三级缓存架构通过分层设计平衡性能、一致性与复杂度,是应对高并发场景的经典方案。实际应用中需结合业务特点灵活调整各级缓存策略,并辅以监控工具(如Prometheus + Grafana)持续优化命中率和响应时间。3. 广播失效本地缓存(如MQ通知)2. 读取分布式缓存。

保持热爱。 1776

Eureka三级缓存架构

Eureka是Netflix开源的服务发现框架,它具有高可用、可扩展、易于部署等优点,被广泛应用于微服务架构中。其中一个重要的组件就是Eureka Server,它负责维护服务注册表,以及向客户端提供服务注册信息。在Eureka Server中,缓存机制是一个非常重要的优化点,它可以显著提升服务注册表的性能和可靠性。本文将深入剖析Eureka Server的缓存机制,并通过源码分析,探讨其实现原理和优化策略。

2301_76166241的博客 2058
上一篇: 强大的Viewpager轮播实现
下一篇: Shape--------详解和运用
有志青年L
博客等级 码龄10年 30粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值