1. 程式人生 > >Redis工具類:支援任意型別物件快取,分散式鎖

Redis工具類:支援任意型別物件快取,分散式鎖

使用到的技術點:泛型返回值,應用redisson實現分散式鎖,redis哨兵部署配置,redis叢集部署配置等。

/**
 * Copyright [email protected]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package framework.webapp.commons.utils;

import framework.webapp.commons.model.AjaxJson;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.redisson.Redisson;
import org.redisson.api.RBucket;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * **************************************************
 * @description redis工具類,底層使用redisson
 * @author karl
 * @version 1.0, 2018-08-17
 * @see HISTORY
 * <p>
 * Date Desc Author Operation
 * </p>
 * <p>
 * 2018-8-17 建立檔案 karl create
 * </p>
 * @since 2017 Phyrose Science & Technology (Kunming) Co., Ltd.
 * ************************************************
 */
public class RedisUtil {

    private static final Log log = LogFactory.getLog(RedisUtil.class);

    private static final String DISTRIBUTED_LOCK_FLAG = "DistributedLock_";

    private static volatile RedissonClient redissonManager;


    public static RedissonClient getRedissonManager() {
        if (redissonManager == null) {
            synchronized (DISTRIBUTED_LOCK_FLAG) {
                if (redissonManager == null) {
                    //使用配置檔案
                    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-redisson.xml");
                    redissonManager = (RedissonClient) applicationContext.getBean("redissonManager");
                    //使用spring容器
                    //redissonManager = ApplicationContextUtil.getBean("redissonManager");
                }
            }
        }
        return redissonManager;
    }

//
//    private static Redisson getRedissonByteArray() {
//        if (redissonByteArray == null) {
//            synchronized (REDISSON_BYTEARRAY_LOCK) {
//               if (redissonByteArray == null) {
//                  redissonByteArray = ApplicationContextUtil.getBean("redissonManager");
//}
//            }
//        }
//        return redissonByteArray;
//    }

     /**
     * 根據name進行上鎖操作,Redisson分散式鎖 阻塞的,採用的機制釋出/訂閱
     * 自定義鎖超時
     * <pre> {@code
     *   try {
     *      RedisUtil.lock(1, TimeUnit.MINUTES);
     *     // manipulate protected state
     *   } finally {
     *     RedisUtil.unlock();
     *   }
     * }
     * </pre>
     *
     * <p>
     * If the lock is not available then the current thread becomes disabled for
     * thread scheduling purposes and lies dormant until the lock has been
     * acquired.
     *
     * If the lock is acquired, it is held until <code>unlock</code> is invoked,
     * or until leaseTime milliseconds have passed since the lock was granted -
     * whichever comes first.
     *
     * @param lockname
     *
     * @param leaseTime the maximum time to hold the lock after granting it,
     * before automatically releasing it if it hasn't already been released by
     * invoking <code>unlock</code>. If leaseTime is -1, hold the lock until
     * explicitly unlocked.
     * @param unit the time unit of the {@code leaseTime} argument
     *
     */
    public static void lock(String lockname, long leaseTime, TimeUnit unit) {
        String key = DISTRIBUTED_LOCK_FLAG + lockname;
        RLock lock = getRedissonManager().getLock(key);
        //lock提供帶timeout引數,timeout結束強制解鎖,防止死鎖 :1分鐘
        lock.lock(leaseTime, unit);
    }

    /**
     * Redisson分散式鎖 根據name進行解鎖操作
     * 與lock一一對應
     * <pre> {@code
     *   try {
     *      RedisUtil.lock(1, TimeUnit.MINUTES);
     *     // manipulate protected state
     *   } finally {
     *     RedisUtil.unlock();
     *   }
     * }
     * </pre>
     *
     * @param lockname
     */
    public static void unlock(String lockname) {
        String key = DISTRIBUTED_LOCK_FLAG + lockname;
        RLock lock = getRedissonManager().getLock(key);
        lock.unlock();
    }

    /**
     * 根據name進行上鎖操作,Redisson分散式鎖 阻塞的,採用的機制釋出/訂閱,鎖超時:預設1分鐘自動釋放鎖
     * <pre> {@code
     *   try {
     *      RedisUtil.lock();
     *     // manipulate protected state
     *   } finally {
     *     RedisUtil.unlock();
     *   }
     * }
     * </pre>
     *
     * @param lockname
     */
    public static void lock(String lockname) {
        String key = DISTRIBUTED_LOCK_FLAG + lockname;
        RLock lock = getRedissonManager().getLock(key);
        //lock提供帶timeout引數,timeout結束強制解鎖,防止死鎖 :1分鐘
        lock.lock(1, TimeUnit.MINUTES);
    }

    /**
     * 從Redis獲取key為name的資料,並封裝為指定class例項,可能發生執行時異常
     *
     * @param <T> 泛型支援
     * @param clazz
     * @param name
     * @return
     */
    public static <T> T get(Class<T> clazz, String name) {
        RBucket<byte[]> keyObject = getRedissonManager().getBucket(name);
        byte[] bytes = keyObject.get();
        if (bytes == null) {
            return null;
        }
        return SerializationUtil.deserialize(clazz, keyObject.get());
    }

    /**
     * 根據name清除資料
     *
     * @param name
     */
    public static void remove(String name) {
        getRedissonManager().getBucket(name).delete();
    }

    /**
     * 快取資料到Redis,無超時
     *
     * @param name
     * @param value
     */
    public static void put(String name, Object value) {
        RBucket<byte[]> keyObject = getRedissonManager().getBucket(name);
        keyObject.set(SerializationUtil.serialize(value));
    }

    /**
     * 快取資料到Redis
     *
     * @param name
     * @param value
     * @param timeToLive
     * @param timeUnit
     */
    public static void put(String name, Object value, long timeToLive, TimeUnit timeUnit) {
        RBucket<byte[]> keyObject = getRedissonManager().getBucket(name);
        keyObject.set(SerializationUtil.serialize(value), timeToLive, timeUnit);
    }

    /**
     * 按分鐘(計算超時)快取資料
     *
     * @param name
     * @param value
     * @param timeToLive
     */
    public static void putCacheWithMinutes(String name, Object value, long timeToLive) {
        RBucket<byte[]> keyObject = getRedissonManager().getBucket(name);
        keyObject.set(SerializationUtil.serialize(value), timeToLive, TimeUnit.MINUTES);
    }

    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:spring-redisson.xml");
        RedissonClient redisson = (RedissonClient) applicationContext.getBean("redissonManager");
        // 首先獲取redis中的key-value物件,key不存在沒關係
       // System.out.println(get(UserEntity.class, DISTRIBUTED_LOCK_FLAG));
        put("keyBytes", "keyBytes");
        System.out.println(get(String.class, "keyBytes"));
        //RBucket<String> keyObject = redisson.getBucket("key");
        //RBucket<byte[]> keyObject = redisson.getBucket("keyBytes");
        //System.out.println("ok:" + keyObject.get());
        // 如果key存在,就設定key的值為新值value
        // 如果key不存在,就設定key的值為value
       // keyObject.set("value".getBytes());
        redisson.shutdown();
    }

}

 maven依賴:spring mvc,apache log

<dependency>  
            <groupId>org.redisson</groupId>  
            <artifactId>redisson</artifactId>  
            <version>3.5.4</version>  
        </dependency>  
        <!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
        <!--redisson 需要用到netty的jar 包-->
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.7.Final</version>
        </dependency>

        <!-- redis相關jar包 -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
            <type>jar</type>
        </dependency>

配置檔案:

spring-redisson.xml

<beans xmlns="http://www.springframework.org/schema/beans"    
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     
    xmlns:context="http://www.springframework.org/schema/context"    
    xmlns:redisson="http://redisson.org/schema/redisson"    
    xsi:schemaLocation="    
       http://www.springframework.org/schema/beans    
       http://www.springframework.org/schema/beans/spring-beans.xsd    
       http://www.springframework.org/schema/context    
       http://www.springframework.org/schema/context/spring-context.xsd    
       http://redisson.org/schema/redisson    
       http://redisson.org/schema/redisson/redisson.xsd">   
     
<!--    <bean id="stringCodec" class="org.redisson.client.codec.StringCodec"></bean> -->
    <bean id="byteArrayCodec" class="org.redisson.client.codec.ByteArrayCodec"></bean> 
     <!-- 單機模式 
    <redisson:client id="redissonManager"   
                     name="standaloneRedisson"  
                     codec-ref="byteArrayCodec">    
        <redisson:single-server address="redis://127.0.0.1:6379"  
                                connection-pool-size="100"  
                                idle-connection-timeout="10000"  
                                connect-timeout="10000"  
                                timeout="3000"  
                                ping-timeout="30000"  
                                reconnection-timeout="30000"  
                                database="0"/>    
    </redisson:client> 
     -->
    <!-- 哨兵部署方式 
     //這裡設定sentinel節點的服務IP和埠,sentinel是採用Paxos拜占庭協議,一般sentinel至少3個節點
    //記住這裡不是配置redis節點的服務埠和IP,sentinel會自己把請求轉發給後面monitor的redis節點
    -->
    <redisson:client id="redissonManager" codec-ref="byteArrayCodec">  
        <redisson:sentinel-servers master-name="redis-master">  
            <redisson:sentinel-address value="redis://127.0.0.1:26379" />  
            <redisson:sentinel-address value="redis://127.0.0.1:26380" />
            <redisson:sentinel-address value="redis://127.0.0.1:26381" />  
        </redisson:sentinel-servers>  
    </redisson:client> 
    
    
    <!-- 叢集方式(cluster) 
    //cluster方式至少6個節點(3主3從,3主做sharding,3從用來保證主宕機後可以高可用)
   
    <redisson:client id="redissonManager" codec-ref="byteArrayCodec">  
        <redisson:cluster-servers scan-interval="500" slaveConnectionPoolSize="500"   
                                  masterConnectionPoolSize="500"   
                                  idle-connection-timeout="10000"    
                                  connect-timeout="10000"    
                                  timeout="3000"    
                                  ping-timeout="1000"    
                                  reconnection-timeout="3000"    
                                  database="0">    
            <redisson:node-address value="redis://127.0.0.1:6379" />  
            <redisson:node-address value="redis://127.0.0.1:16379" />
            <redisson:node-address value="redis://127.0.0.1:6380" />  
            <redisson:node-address value="redis://127.0.0.1:16380" />  
            <redisson:node-address value="redis://127.0.0.1:6381" />  
            <redisson:node-address value="redis://127.0.0.1:16381" /> 
        </redisson:cluster-servers>  
    </redisson:client>  
       -->
</beans>    

redis哨兵配置示例sentinel-26379.conf:

##sentinel例項之間的通訊埠

daemonize yes

port 26379

#redis-master

sentinel myid 9028ea0dc586c123e58dca922f4ce406e7666cb6

sentinel monitor redis-master 127.0.0.1 6379 1

sentinel down-after-milliseconds redis-master 5000

sentinel failover-timeout redis-master 900000

#sentinel auth-pass redis-master 123456

logfile "./sentinel.log"
 

redis叢集從配置示例redis16379-slave.conf:


bind 127.0.0.1

protected-mode yes


port 16379


tcp-backlog 511

# Close the connection after a client is idle for N seconds (0 to disable)
timeout 0


# A reasonable value for this option is 60 seconds.
tcp-keepalive 0

# Specify the server verbosity level.
# This can be one of:
# debug (a lot of information, useful for development/testing)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel notice

# Specify the log file name. Also 'stdout' can be used to force
# Redis to log on the standard output.
logfile ""

# Set the number of databases. The default database is DB 0, you can select
# a different one on a per-connection basis using SELECT <dbid> where
# dbid is a number between 0 and 'databases'-1
databases 16

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000


stop-writes-on-bgsave-error yes


rdbcompression yes


rdbchecksum yes

# The filename where to dump the DB
dbfilename dump.rdb


dir ./


slaveof 127.0.0.1 6379

# If the master is password protected (using the "requirepass" configuration
# directive below) it is possible to tell the slave to authenticate before
# starting the replication synchronization process, otherwise the master will
# refuse the slave request.
#
# masterauth <master-password>

# When a slave loses its connection with the master, or when the replication
# is still in progress, the slave can act in two different ways:
#
# 1) if slave-serve-stale-data is set to 'yes' (the default) the slave will
#    still reply to client requests, possibly with out of date data, or the
#    data set may just be empty if this is the first synchronization.
#
# 2) if slave-serve-stale-data is set to 'no' the slave will reply with
#    an error "SYNC with master in progress" to all the kind of commands
#    but to INFO and SLAVEOF.
#
slave-serve-stale-data yes


slave-read-only yes


repl-diskless-sync no


repl-diskless-sync-delay 5

# Slaves send PINGs to server in a predefined interval. It's possible to change
# this interval with the repl_ping_slave_period option. The default value is 10
# seconds.
#
# repl-ping-slave-period 10

# The following option sets the replication timeout for:
#
# 1) Bulk transfer I/O during SYNC, from the point of view of slave.
# 2) Master timeout from the point of view of slaves (data, pings).
# 3) Slave timeout from the point of view of masters (REPLCONF ACK pings).
#
# It is important to make sure that this value is greater than the value
# specified for repl-ping-slave-period otherwise a timeout will be detected
# every time there is low traffic between the master and the slave.
#
# repl-timeout 60


repl-disable-tcp-nodelay no


slave-priority 100

################################### LIMITS ####################################

# Set the max number of connected clients at the same time. By default
# this limit is set to 10000 clients, however if the Redis server is not
# able to configure the process file limit to allow for the specified limit
# the max number of allowed clients is set to the current file limit
# minus 32 (as Redis reserves a few file descriptors for internal uses).
#
# Once the limit is reached Redis will close all the new connections sending
# an error 'max number of clients reached'.
#
# maxclients 10000

# If Redis is to be used as an in-memory-only cache without any kind of
# persistence, then the fork() mechanism used by the background AOF/RDB
# persistence is unnecessary. As an optimization, all persistence can be
# turned off in the Windows version of Redis. This will redirect heap
# allocations to the system heap allocator, and disable commands that would
# otherwise cause fork() operations: BGSAVE and BGREWRITEAOF.
# This flag may not be combined with any of the other flags that configure
# AOF and RDB operations.
# persistence-available [(yes)|no]

# Don't use more memory than the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU cache, or to set
# a hard memory limit for an instance (using the 'noeviction' policy).
#
# WARNING: If you have slaves attached to an instance with maxmemory on,
# the size of the output buffers needed to feed the slaves are subtracted
# from the used memory count, so that network problems / resyncs will
# not trigger a loop where keys are evicted, and in turn the output
# buffer of slaves is full with DELs of keys evicted triggering the deletion
# of more keys, and so forth until the database is completely emptied.
#
# In short... if you have slaves attached it is suggested that you set a lower
# limit for maxmemory so that there is some free RAM on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# WARNING: not setting maxmemory will cause Redis to terminate with an
# out-of-memory exception if the heap limit is reached.
#
# NOTE: since Redis uses the system paging file to allocate the heap memory,
# the Working Set memory usage showed by the Windows Task Manager or by other
# tools such as ProcessExplorer will not always be accurate. For example, right
# after a background save of the RDB or the AOF files, the working set value
# may drop significantly. In order to check the correct amount of memory used
# by the redis-server to store the data, use the INFO client command. The INFO
# command shows only the memory used to store the redis data, not the extra
# memory used by the Windows process for its own requirements. Th3 extra amount
# of memory not reported by the INFO command can be calculated subtracting the
# Peak Working Set reported by the Windows Task Manager and the used_memory_peak
# reported by the INFO command.
#
# maxmemory <bytes>


appendonly no

# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"

# The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.
#
# Redis supports three different modes:
#
# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.
#

# If unsure, use "everysec".

# appendfsync always
appendfsync everysec

no-appendfsync-on-rewrite no

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

aof-load-truncated yes


lua-time-limit 5000


slowlog-log-slower-than 10000


slowlog-max-len 128



latency-monitor-threshold 0


hash-max-ziplist-entries 512
hash-max-ziplist-value 64


list-max-ziplist-size -2



list-compress-depth 0


set-max-intset-entries 512


zset-max-ziplist-entries 128
zset-max-ziplist-value 64


hll-sparse-max-bytes 3000


client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60


hz 10


附記:

為方便讀者測試redis哨兵部署和叢集部署效果,共享一個一鍵本地啟動java工具類,配置檔案請參考如上所示,並修改相應埠(哨兵部署需要複製並修改生成3個,叢集部署需要複製並修改生成6個)。


import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by dufy on 2017/3/28.
 *
 * cmd /c dir 是執行完dir命令後關閉命令視窗。<br/>
 * cmd /k dir 是執行完dir命令後不關閉命令視窗.<br/>
 * cmd /c start dir 會開啟一個新視窗後執行dir指令,原視窗會關閉。<br/>
 * cmd /k start dir 會開啟一個新視窗後執行dir指令,原視窗不會關閉。<br/>
 * redis-cli.exe -h 127.0.0.1 -p 埠<br/>
 * info replication -- 檢視主從複製<br/>
 * info sentinel-- 檢視哨兵情況<br/>
 *
 * window本地搭redis的哨兵模式:http://blog.csdn.net/liuchuanhong1/article/details/53206028<br/><br/>
 *
 * 啟動服務工具類
 */
public class StartRedisServer {

    private final static String redisRootPath = "E:/Redis-x64-3.2.100";

    public static void main(String[] args) {
        List<String> cmds = new ArrayList<String>();
        //三主三從叢集模式
        String cmdRedis6379 = "cmd /k start redis-server.exe redis6379.conf ";//redis-server.exe master redis.conf
        String cmdRedis16379 = "cmd /k start redis-server.exe redis16379-slave.conf ";//redis-server.exe slave redis.conf
        String cmdRedis6380 = "cmd /k start redis-server.exe redis6380.conf ";//redis-server.exe master  redis.conf
        String cmdRedis16380 = "cmd /k start redis-server.exe redis16380-slave.conf ";//redis-server.exe slave redis.conf
        String cmdRedis6381 = "cmd /k start redis-server.exe redis6381.conf ";//redis-server.exe master  redis.conf
        String cmdRedis16381 = "cmd /k start redis-server.exe redis16381-slave.conf ";//redis-server.exe slave redis.conf

//        cmds.add(cmdRedis6379);
//        cmds.add(cmdRedis16389);
//        cmds.add(cmdRedis6380);
//        cmds.add(cmdRedis16380);
//        cmds.add(cmdRedis6381);
//        cmds.add(cmdRedis16381);

        //哨兵模式
        String cmdRedis26379 = "cmd /k start redis-server.exe sentinel-26379.conf --sentinel";//redis-server.exe sentinel26479.conf --sentinel
        String cmdRedis26479 = "cmd /k start redis-server.exe sentinel-26380.conf --sentinel";//redis-server.exe sentinel26479.conf --sentinel
        String cmdRedis26579 = "cmd /k start redis-server.exe sentinel-26381.conf --sentinel";//redis-server.exe sentinel26479.conf --sentinel

        cmds.add(cmdRedis26379);
        cmds.add(cmdRedis26479);
        cmds.add(cmdRedis26579);

        initRedisServer(cmds);
    }

    public static void initRedisServer(List<String> cmdStr) {
        if (cmdStr != null && cmdStr.size() > 0) {
            for (String cmd : cmdStr) {
                try {
                    Process exec = Runtime.getRuntime().exec(cmd, null, new File(redisRootPath));
                    Thread.sleep(1 * 1000);
                } catch (InterruptedException e) {
                    System.out.println("執行緒中斷異常" + e.getMessage());
                    e.printStackTrace();
                } catch (IOException e) {
                    System.out.println("cmd command error" + e.getMessage());
                    e.printStackTrace();
                }

            }
        }

    }
}

相關推薦

Redis工具支援任意型別物件快取,分散式

使用到的技術點:泛型返回值,應用redisson實現分散式鎖,redis哨兵部署配置,redis叢集部署配置等。 /** * Copyright [email protected] * * Licensed under the Apache Lice

Redis工具對各種資料型別的操作

import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.*; import org.springframework.stereotype.Service;

jedis工具java操作redis資料庫

學完redis,需要在java客戶端中使用Jedis,作為連線redis的工具: JedisUtils工具類: public class JedisUtils{ //定義一個連線池物件: private final static JedisPool POOL; static {

安卓 SharedPreferences 工具支援物件存取)

一、快取輔助類 import android.content.Context; import android.content.SharedPreferences; import java.lang.reflect.InvocationTargetExcepti

Java封裝 Redis 工具

首先是一個定義 Redis 的 Key 介面類,記錄 key 值(字首)與快取的時間: public interface KeyPrefix { public int expireSeconds(); public String ge

工具關於如何找到兩個List數組中不同的數據的算法!

開發人員 uri print clas 數據結構 blank _id integer public 找到兩個List數組中不同的數據的算法! import java.util.ArrayList;import java.util.HashMap;import java.ut

Java之工具判斷對象是否為空或null

sar 判斷 ins == span urn lean color style 1 import java.lang.reflect.Array; 2 import java.util.Collection; 3 import java.util.Map; 4

Java中的AES加解密工具AESUtils

.com asc += for frame day 換行 fault mod 本人手寫已測試,大家可以參考使用 package com.mirana.frame.utils.encrypt; import com.mirana.frame.constants.SysC

spring專案中 通過自定義applicationContext工具獲取到applicationContext上下文物件

spring專案在伺服器啟動的時候 spring容器中就已經被建立好了各種物件,在我們需要使用的時候可以進行呼叫. 工具類程式碼如下 import org.springframework.beans.BeansException; import org.springframewo

貨幣顯示工具會計格式,非科學計數法等

package chanson; import java.math.BigDecimal; import java.math.RoundingMode; /** * @title 貨幣顯示處理工具類 * @detail 包含以下內容: * 1、四捨五入求值 * 2、針對不同的格式化

php操作redis工具

config.php <?php // //redis配置 define('HOST','localhost'); define('PORT', '6379'); define('OVERTIME', '0'); ?> Redistool.php <?php inclu

工具Toast

package com.sikkha.skline.utils; import android.annotation.SuppressLint; import android.content.Context; import android.view.Gravity; import android.

工具點選擴大點選區域的

package com.sikkha.skline.utils; import android.graphics.Rect; import android.view.TouchDelegate; import android.view.View; /** * =================

工具防抖動(極短時間多次點選,導致介面彈出多個dialog)

工具類: public class OnClickUtils {     // 兩次點選按鈕之間的點選間隔不能少於500毫秒     private static final int MIN_CLICK_DELAY_TIME = 500;   &

redis工具學習和使用(RedisTemplate,StringRedisTemplate)

RedisTemplate ,StringRedisTemplate 是對redis操作的一個封裝類.類似jdbcTemplate RedisTemplate是一個泛型類,RedisTemplate可以對任何型別的key-value鍵值對操作。(hash結構同

#Java--POI之Excel匯出工具支援多個sheet頁同時匯出)

一、核心程式碼 package com.yx.yzh.utils; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.

Springboot 與 Redis 整合 簡易Redis工具實現

最近專案需要處理一項資料量比較大的業務,考慮之下,高頻訪問/讀取決定使用Redis.自己的Springboot框架下研究了Redis兩天,把成果總結一下 開發環境介紹 JDK1.7 Redis 基礎依賴 org.mybatis.spring.boot myba

Java常用工具java.util.Arrays

陣列操作工具類-java.util.Arrays java.util.Arrays類能方便的運算元組,測試的時候造資料經常用到一下方法。 1.filll方法 :給陣列中的某段元素附上相同值。 int []arr = new int[5]; Arrays.fill(arr, 2); for

高效Redis工具

一、引言 本篇部落格以redis快取為主。至於什麼是redis快取?還有沒有其它的快取?哪個快取的效能會更好?這裡就不一一做介紹了!(有興趣的可以自己去百度一下) 在日常的開發中,我們或多或少(必須)的會用到快取。為了提高系統性能、提升使用者體驗度,使用者體驗是多麼的重要;這就要求在軟體設計

[Google Guava] 2.3-強大的集合工具java.util.Collections中未包含的集合工具

原文連結 譯文連結 譯者:沈義揚,校對:丁一 尚未完成: Queues, Tables工具類 任何對JDK集合框架有經驗的程式設計師都熟悉和喜歡java.util.Collections包含的工具方法。Guava沿著這些路線提供了更多的工具方法:適用於所有集合的靜態方法。這是Guava最流行和