欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringData實(shí)現(xiàn)自定義Redis緩存的序列化機(jī)制和過期策略

 更新時(shí)間:2025年04月13日 10:39:38   作者:程序媛學(xué)姐  
Spring Data Redis緩存通過提供靈活的配置選項(xiàng),使開發(fā)者能夠根據(jù)業(yè)務(wù)需求自定義序列化方式和過期策略,下面就來具體介紹一下,感興趣的可以了解一下

引言

在現(xiàn)代高并發(fā)分布式系統(tǒng)中,緩存扮演著至關(guān)重要的角色。Spring Data Redis提供了強(qiáng)大的緩存抽象層,使開發(fā)者能夠輕松地在應(yīng)用中集成Redis緩存。本文將深入探討如何自定義Redis緩存的序列化機(jī)制和過期策略,幫助開發(fā)者解決緩存數(shù)據(jù)一致性、內(nèi)存占用和訪問效率等關(guān)鍵問題。通過合理配置Spring Cache注解和RedisCache實(shí)現(xiàn),可顯著提升應(yīng)用性能,減輕數(shù)據(jù)庫壓力。

一、Spring Cache與Redis集成基礎(chǔ)

Spring Cache是Spring框架提供的緩存抽象,它允許開發(fā)者以聲明式方式定義緩存行為,而無需編寫底層緩存邏輯。結(jié)合Redis作為緩存提供者,可以構(gòu)建高性能的分布式緩存系統(tǒng)。Spring Cache支持多種注解,如@Cacheable、@CachePut、@CacheEvict等,分別用于緩存查詢結(jié)果、更新緩存和刪除緩存。Redis的高性能和豐富的數(shù)據(jù)結(jié)構(gòu)使其成為理想的緩存存儲(chǔ)選擇。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@SpringBootApplication
@EnableCaching  // 啟用Spring緩存支持
public class RedisCacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(RedisCacheApplication.class, args);
    }
}

二、Redis緩存配置基礎(chǔ)

配置Redis緩存需要?jiǎng)?chuàng)建RedisCacheManager和定義基本的緩存屬性。RedisCacheManager負(fù)責(zé)創(chuàng)建和管理RedisCache實(shí)例,而RedisCache則實(shí)現(xiàn)了Spring的Cache接口?;九渲冒ㄔO(shè)置Redis連接工廠、默認(rèn)過期時(shí)間和緩存名稱前綴等。通過RedisCacheConfiguration可以自定義序列化方式、過期策略和鍵前綴等。這些配置對緩存的性能和可用性有直接影響。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import java.time.Duration;

@Configuration
public class RedisCacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        // 創(chuàng)建默認(rèn)的Redis緩存配置
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                // 設(shè)置緩存有效期為1小時(shí)
                .entryTtl(Duration.ofHours(1))
                // 設(shè)置鍵前綴
                .prefixCacheNameWith("app:cache:");
        
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(config)
                .build();
    }
}

三、自定義序列化策略

默認(rèn)情況下,Spring Data Redis使用JDK序列化,這種方式存在效率低、占用空間大、可讀性差等問題。自定義序列化策略可以顯著改善這些問題。常用的序列化方式包括JSON、ProtoBuf和Kryo等。其中JSON序列化便于調(diào)試但性能一般,ProtoBuf和Kryo則提供更高的性能和更小的存儲(chǔ)空間。選擇合適的序列化方式需要在性能、空間效率和可讀性之間做權(quán)衡。

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisSerializerConfig {

    @Bean
    public RedisCacheConfiguration cacheConfiguration() {
        // 創(chuàng)建自定義的ObjectMapper,用于JSON序列化
        ObjectMapper mapper = new ObjectMapper();
        // 啟用類型信息,確保反序列化時(shí)能夠正確恢復(fù)對象類型
        mapper.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.PROPERTY
        );
        
        // 創(chuàng)建基于Jackson的Redis序列化器
        GenericJackson2JsonRedisSerializer jsonSerializer = 
                new GenericJackson2JsonRedisSerializer(mapper);
        
        // 配置Redis緩存使用String序列化器處理鍵,JSON序列化器處理值
        return RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(
                                new StringRedisSerializer()))
                .serializeValuesWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(
                                jsonSerializer));
    }
}

四、實(shí)現(xiàn)自定義序列化器

在某些場景下,Spring提供的序列化器可能無法滿足特定需求,此時(shí)需要實(shí)現(xiàn)自定義序列化器。自定義序列化器需要實(shí)現(xiàn)RedisSerializer接口,覆蓋serialize和deserialize方法。通過自定義序列化器,可以實(shí)現(xiàn)特定對象的高效序列化,或者為序列化添加額外的安全措施,如加密解密等。實(shí)現(xiàn)時(shí)需注意處理序列化異常和空值情況。

import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;

import java.io.ByteArrayOutputStream;

public class KryoRedisSerializer<T> implements RedisSerializer<T> {
    
    private final Class<T> clazz;
    private static final ThreadLocal<Kryo> kryoThreadLocal = ThreadLocal.withInitial(() -> {
        Kryo kryo = new Kryo();
        // 配置Kryo實(shí)例
        kryo.setRegistrationRequired(false); // 不要求注冊類
        return kryo;
    });
    
    public KryoRedisSerializer(Class<T> clazz) {
        this.clazz = clazz;
    }
    
    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return new byte[0];
        }
        
        Kryo kryo = kryoThreadLocal.get();
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
             Output output = new Output(baos)) {
            kryo.writeObject(output, t);
            output.flush();
            return baos.toByteArray();
        } catch (Exception e) {
            throw new SerializationException("Error serializing object using Kryo", e);
        }
    }
    
    @Override
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        
        Kryo kryo = kryoThreadLocal.get();
        try (Input input = new Input(bytes)) {
            return kryo.readObject(input, clazz);
        } catch (Exception e) {
            throw new SerializationException("Error deserializing object using Kryo", e);
        }
    }
}

五、多級緩存配置

在實(shí)際應(yīng)用中,往往需要為不同類型的數(shù)據(jù)配置不同的緩存策略。Spring Cache支持定義多個(gè)緩存,每個(gè)緩存可以有獨(dú)立的配置。通過RedisCacheManagerBuilderCustomizer可以為不同的緩存名稱定制配置,如設(shè)置不同的過期時(shí)間、序列化方式和前綴策略等。多級緩存配置能夠針對業(yè)務(wù)特點(diǎn)優(yōu)化緩存性能。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheManager.RedisCacheManagerBuilder;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MultiLevelCacheConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory,
                                          RedisCacheConfiguration defaultConfig) {
        // 創(chuàng)建不同緩存空間的配置映射
        Map<String, RedisCacheConfiguration> configMap = new HashMap<>();
        
        // 用戶緩存:過期時(shí)間30分鐘
        configMap.put("userCache", defaultConfig.entryTtl(Duration.ofMinutes(30)));
        
        // 產(chǎn)品緩存:過期時(shí)間2小時(shí)
        configMap.put("productCache", defaultConfig.entryTtl(Duration.ofHours(2)));
        
        // 熱點(diǎn)數(shù)據(jù)緩存:過期時(shí)間5分鐘
        configMap.put("hotDataCache", defaultConfig.entryTtl(Duration.ofMinutes(5)));
        
        // 創(chuàng)建并配置RedisCacheManager
        return RedisCacheManager.builder(connectionFactory)
                .cacheDefaults(defaultConfig)
                .withInitialCacheConfigurations(configMap)
                .build();
    }
}

六、自定義過期策略

緩存過期策略直接影響緩存的有效性和資源消耗。Spring Data Redis支持多種過期設(shè)置方式,包括全局統(tǒng)一過期時(shí)間、按緩存名稱設(shè)置過期時(shí)間,以及根據(jù)緩存內(nèi)容動(dòng)態(tài)設(shè)置過期時(shí)間。合理的過期策略有助于平衡緩存命中率和數(shù)據(jù)新鮮度。對于不同更新頻率的數(shù)據(jù),應(yīng)設(shè)置不同的過期時(shí)間以獲得最佳效果。

import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.CacheKeyPrefix;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;

import java.lang.reflect.Method;
import java.time.Duration;
import java.util.Objects;

@Configuration
public class CustomExpirationConfig {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
        // 創(chuàng)建自定義的RedisCacheWriter
        RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
        
        // 默認(rèn)緩存配置
        RedisCacheConfiguration defaultConfig = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofHours(1)); // 默認(rèn)過期時(shí)間1小時(shí)
        
        // 創(chuàng)建支持動(dòng)態(tài)TTL的RedisCacheManager
        return new DynamicTtlRedisCacheManager(cacheWriter, defaultConfig);
    }
    
    // 自定義緩存鍵生成器,考慮方法名和參數(shù)
    @Bean
    public KeyGenerator customKeyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getSimpleName())
                  .append(":")
                  .append(method.getName());
                
                for (Object param : params) {
                    if (param != null) {
                        sb.append(":").append(param.toString());
                    }
                }
                
                return sb.toString();
            }
        };
    }
    
    // 自定義RedisCacheManager,支持動(dòng)態(tài)TTL
    static class DynamicTtlRedisCacheManager extends RedisCacheManager {
        
        public DynamicTtlRedisCacheManager(RedisCacheWriter cacheWriter,
                                          RedisCacheConfiguration defaultConfig) {
            super(cacheWriter, defaultConfig);
        }
        
        @Override
        protected RedisCache createRedisCache(String name, RedisCacheConfiguration config) {
            // 根據(jù)緩存名稱動(dòng)態(tài)設(shè)置TTL
            if (name.startsWith("userActivity")) {
                config = config.entryTtl(Duration.ofMinutes(15));
            } else if (name.startsWith("product")) {
                config = config.entryTtl(Duration.ofHours(4));
            } else if (name.startsWith("config")) {
                config = config.entryTtl(Duration.ofDays(1));
            }
            
            return super.createRedisCache(name, config);
        }
    }
}

七、緩存注解的高級應(yīng)用

Spring Cache提供了豐富的注解用于管理緩存,包括@Cacheable、@CachePut、@CacheEvict和@Caching等。這些注解能夠精細(xì)控制緩存行為,如何何時(shí)緩存結(jié)果、更新緩存和清除緩存。通過condition和unless屬性,可以實(shí)現(xiàn)條件緩存,只有滿足特定條件的結(jié)果才會(huì)被緩存。合理使用這些注解可以提高緩存的命中率和有效性。

import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

    private final ProductRepository repository;
    
    public ProductService(ProductRepository repository) {
        this.repository = repository;
    }
    
    /**
     * 根據(jù)ID查詢產(chǎn)品,結(jié)果會(huì)被緩存
     * 條件:產(chǎn)品價(jià)格大于100才緩存
     */
    @Cacheable(
        value = "productCache",
        key = "#id",
        condition = "#id > 0",
        unless = "#result != null && #result.price <= 100"
    )
    public Product findById(Long id) {
        // 模擬從數(shù)據(jù)庫查詢
        return repository.findById(id).orElse(null);
    }
    
    /**
     * 更新產(chǎn)品信息并更新緩存
     */
    @CachePut(value = "productCache", key = "#product.id")
    public Product updateProduct(Product product) {
        return repository.save(product);
    }
    
    /**
     * 刪除產(chǎn)品并清除相關(guān)緩存
     * allEntries=true表示清除所有productCache的緩存項(xiàng)
     */
    @CacheEvict(value = "productCache", key = "#id", allEntries = false)
    public void deleteProduct(Long id) {
        repository.deleteById(id);
    }
    
    /**
     * 復(fù)合緩存操作:同時(shí)清除多個(gè)緩存
     */
    @Caching(
        evict = {
            @CacheEvict(value = "productCache", key = "#id"),
            @CacheEvict(value = "categoryProductsCache", key = "#product.categoryId")
        }
    )
    public void deleteProductWithRelations(Long id, Product product) {
        repository.deleteById(id);
    }
}

八、實(shí)現(xiàn)緩存預(yù)熱與更新策略

緩存預(yù)熱是指在系統(tǒng)啟動(dòng)時(shí)提前加載熱點(diǎn)數(shù)據(jù)到緩存中,以避免系統(tǒng)啟動(dòng)初期大量緩存未命中導(dǎo)致的性能問題。緩存更新策略則關(guān)注如何保持緩存數(shù)據(jù)與數(shù)據(jù)庫數(shù)據(jù)的一致性。常見的更新策略包括失效更新、定時(shí)更新和異步更新等。合理的緩存預(yù)熱與更新策略能夠提高系統(tǒng)的響應(yīng)速度和穩(wěn)定性。

import org.springframework.boot.CommandLineRunner;
import org.springframework.cache.CacheManager;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
public class CacheWarmer implements CommandLineRunner {

    private final ProductRepository productRepository;
    private final CacheManager cacheManager;
    private final RedisTemplate<String, Object> redisTemplate;
    
    public CacheWarmer(ProductRepository productRepository,
                       CacheManager cacheManager,
                       RedisTemplate<String, Object> redisTemplate) {
        this.productRepository = productRepository;
        this.cacheManager = cacheManager;
        this.redisTemplate = redisTemplate;
    }
    
    /**
     * 系統(tǒng)啟動(dòng)時(shí)執(zhí)行緩存預(yù)熱
     */
    @Override
    public void run(String... args) {
        System.out.println("Performing cache warming...");
        
        // 加載熱門產(chǎn)品到緩存
        List<Product> hotProducts = productRepository.findTop100ByOrderByViewsDesc();
        for (Product product : hotProducts) {
            String cacheKey = "productCache::" + product.getId();
            redisTemplate.opsForValue().set(cacheKey, product);
            
            // 設(shè)置差異化過期時(shí)間,避免同時(shí)過期
            long randomTtl = 3600 + (long)(Math.random() * 1800); // 1小時(shí)到1.5小時(shí)之間的隨機(jī)值
            redisTemplate.expire(cacheKey, randomTtl, TimeUnit.SECONDS);
        }
        
        System.out.println("Cache warming completed, loaded " + hotProducts.size() + " products");
    }
    
    /**
     * 定時(shí)更新熱點(diǎn)數(shù)據(jù)緩存,每小時(shí)執(zhí)行一次
     */
    @Scheduled(fixedRate = 3600000)
    public void refreshHotDataCache() {
        System.out.println("Refreshing hot data cache...");
        
        // 獲取最新的熱點(diǎn)數(shù)據(jù)
        List<Product> latestHotProducts = productRepository.findTop100ByOrderByViewsDesc();
        
        // 更新緩存
        for (Product product : latestHotProducts) {
            redisTemplate.opsForValue().set("productCache::" + product.getId(), product);
        }
    }
}

九、緩存監(jiān)控與統(tǒng)計(jì)

緩存監(jiān)控是緩存管理的重要組成部分,通過監(jiān)控可以了解緩存的使用情況、命中率、內(nèi)存占用等關(guān)鍵指標(biāo)。Spring Boot Actuator結(jié)合Micrometer可以收集緩存統(tǒng)計(jì)數(shù)據(jù)并通過Prometheus等監(jiān)控系統(tǒng)進(jìn)行可視化展示。通過監(jiān)控?cái)?shù)據(jù)可以及時(shí)發(fā)現(xiàn)緩存問題并進(jìn)行優(yōu)化,如調(diào)整緩存大小、過期時(shí)間和更新策略等。

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

@Aspect
@Component
public class CacheMonitorAspect {

    private final MeterRegistry meterRegistry;
    private final ConcurrentHashMap<String, AtomicLong> cacheHits = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, AtomicLong> cacheMisses = new ConcurrentHashMap<>();
    
    public CacheMonitorAspect(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    /**
     * 監(jiān)控緩存方法的執(zhí)行情況
     */
    @Around("@annotation(org.springframework.cache.annotation.Cacheable)")
    public Object monitorCacheable(ProceedingJoinPoint joinPoint) throws Throwable {
        String methodName = joinPoint.getSignature().toShortString();
        Timer.Sample sample = Timer.start(meterRegistry);
        
        // 方法執(zhí)行前標(biāo)記,用于判斷是否走了緩存
        boolean methodExecuted = false;
        
        try {
            Object result = joinPoint.proceed();
            methodExecuted = true;
            return result;
        } finally {
            // 記錄方法執(zhí)行時(shí)間
            sample.stop(meterRegistry.timer("cache.access.time", "method", methodName));
            
            // 更新緩存命中/未命中計(jì)數(shù)
            if (methodExecuted) {
                // 方法被執(zhí)行,說明緩存未命中
                cacheMisses.computeIfAbsent(methodName, k -> {
                    AtomicLong counter = new AtomicLong(0);
                    meterRegistry.gauge("cache.miss.count", counter);
                    return counter;
                }).incrementAndGet();
            } else {
                // 方法未執(zhí)行,說明命中緩存
                cacheHits.computeIfAbsent(methodName, k -> {
                    AtomicLong counter = new AtomicLong(0);
                    meterRegistry.gauge("cache.hit.count", counter);
                    return counter;
                }).incrementAndGet();
            }
        }
    }
}

總結(jié)

Spring Data Redis緩存通過提供靈活的配置選項(xiàng),使開發(fā)者能夠根據(jù)業(yè)務(wù)需求自定義序列化方式和過期策略。合理的序列化機(jī)制可顯著提升緩存效率,減少網(wǎng)絡(luò)傳輸和存儲(chǔ)空間消耗。而科學(xué)的過期策略則能平衡數(shù)據(jù)一致性和緩存命中率,避免緩存穿透和雪崩等問題。在實(shí)際應(yīng)用中,緩存策略應(yīng)結(jié)合業(yè)務(wù)特點(diǎn)進(jìn)行差異化配置,如對熱點(diǎn)數(shù)據(jù)設(shè)置較短過期時(shí)間以保證數(shù)據(jù)新鮮度,對變更不頻繁的配置數(shù)據(jù)設(shè)置較長過期時(shí)間以減少數(shù)據(jù)庫查詢。通過緩存預(yù)熱、更新策略和監(jiān)控體系的建立,可以構(gòu)建高性能、高可靠的分布式緩存系統(tǒng),有效支撐大規(guī)模并發(fā)訪問的業(yè)務(wù)需求。

到此這篇關(guān)于SpringData實(shí)現(xiàn)自定義Redis緩存的序列化機(jī)制和過期策略的文章就介紹到這了,更多相關(guān)SpringData實(shí)現(xiàn)序列化機(jī)制和過期策略內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis-Plus批量插入用法詳解

    Mybatis-Plus批量插入用法詳解

    mybatis-plus的IService接口默認(rèn)提供saveBatch批量插入,也是唯一一個(gè)默認(rèn)批量插入,在數(shù)據(jù)量不是很大的情況下可以直接使用,但這種是一條一條執(zhí)行的效率上會(huì)有一定的瓶頸,今天我們就來研究研究mybatis-plus中的批量插入
    2023-02-02
  • Quartz集群原理以及配置應(yīng)用的方法詳解

    Quartz集群原理以及配置應(yīng)用的方法詳解

    Quartz是Java領(lǐng)域最著名的開源任務(wù)調(diào)度工具。Quartz提供了極為廣泛的特性如持久化任務(wù),集群和分布式任務(wù)等,下面這篇文章主要給大家介紹了關(guān)于Quartz集群原理以及配置應(yīng)用的相關(guān)資料,需要的朋友可以參考下
    2018-05-05
  • Idea如何導(dǎo)入一個(gè)SpringBoot項(xiàng)目的方法(圖文教程)

    Idea如何導(dǎo)入一個(gè)SpringBoot項(xiàng)目的方法(圖文教程)

    這篇文章主要介紹了Idea如何導(dǎo)入一個(gè)SpringBoot項(xiàng)目的方法(圖文教程),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Mybatis執(zhí)行update失敗的解決

    Mybatis執(zhí)行update失敗的解決

    這篇文章主要介紹了Mybatis執(zhí)行update失敗的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot實(shí)現(xiàn)熱部署的三種方式

    SpringBoot實(shí)現(xiàn)熱部署的三種方式

    本文主要介紹了SpringBoot實(shí)現(xiàn)熱部署的三種方式,主要包括配置pom.xml文件,使用插件的執(zhí)行命令mvn spring-boot:run啟動(dòng)項(xiàng),使用springloader本地啟動(dòng)修改jvm參數(shù),使用devtools工具包,感興趣的可以了解一下
    2023-12-12
  • Java設(shè)計(jì)模式之備忘錄模式實(shí)現(xiàn)對象狀態(tài)的保存和恢復(fù)

    Java設(shè)計(jì)模式之備忘錄模式實(shí)現(xiàn)對象狀態(tài)的保存和恢復(fù)

    本文介紹Java設(shè)計(jì)模式之備忘錄模式,該模式可以實(shí)現(xiàn)對象狀態(tài)的保存和恢復(fù)。通過詳細(xì)講解備忘錄模式的原理、實(shí)現(xiàn)方法和應(yīng)用場景,幫助讀者深入理解該設(shè)計(jì)模式,并提供示例代碼和技巧,便于讀者實(shí)際應(yīng)用
    2023-04-04
  • JavaWeb中的組件Filter過濾器解析

    JavaWeb中的組件Filter過濾器解析

    這篇文章主要介紹了JavaWeb中的組件Filter過濾器解析,Filter過濾器是一種用于處理和轉(zhuǎn)換數(shù)據(jù)的工具,常用于Web開發(fā)中,它可以在請求到達(dá)服務(wù)器之前或響應(yīng)返回給客戶端之前對數(shù)據(jù)進(jìn)行預(yù)處理或后處理,需要的朋友可以參考下
    2023-10-10
  • springboot整合gateway的詳細(xì)過程

    springboot整合gateway的詳細(xì)過程

    本文介紹了如何配置和使用Spring Cloud Gateway構(gòu)建一個(gè)API網(wǎng)關(guān),通過實(shí)例代碼介紹了springboot整合gateway的過程,需要的朋友可以參考下
    2025-01-01
  • java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換詳解

    java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換詳解

    這篇文章主要為大家詳細(xì)介紹了java DateUtil工具類時(shí)間戳類型轉(zhuǎn)換的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組(動(dòng)力節(jié)點(diǎn)之Java學(xué)院整理)

    Java數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組(動(dòng)力節(jié)點(diǎn)之Java學(xué)院整理)

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)之?dāng)?shù)組(動(dòng)力節(jié)點(diǎn)之Java學(xué)院整理)的相關(guān)資料,包括創(chuàng)建和內(nèi)存分配,數(shù)組封裝后的使用等,需要的朋友參考下吧
    2017-04-04

最新評論