天天看點

Redi總結 -- springboot中redisTemplate源碼分析

文章目錄

  • ​​一,RedisOperations​​
  • ​​二,RedisAccessor​​
  • ​​三,RedisTemplate​​
  • ​​1.序列化配置​​
  • ​​2.連接配接擷取和關閉​​
在上文中我們知道了redisTemplate是springboot中操作redis的核心,今天來進一步了解了解其内部實作

繼承關系

public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {

    //````````````
}      

分析的順序會按照從父到子,從接口到實作的順序

一,RedisOperations

RedisOperations接口定義了redisTemplate操作redis的一些api方法,主要提供了一些對Redis鍵,事務,運作腳本等指令的支援,不負責資料的讀寫,具體實作類有兩個,

StringRedisTemplate

RedisTemplate      

根據泛型類型的參數有不同的實作

二,RedisAccessor

RedisAccessor主要就是對連接配接工廠的配置,實作了InitializingBean接口,在初始化bean時會斷言是否已經配置連接配接工廠

public class RedisAccessor implements InitializingBean {
    protected final Log logger = LogFactory.getLog(this.getClass());
    @Nullable
    private RedisConnectionFactory connectionFactory;

    public RedisAccessor() {
    }

    public void afterPropertiesSet() {
        Assert.state(this.getConnectionFactory() != null, "RedisConnectionFactory is required");
    }

    @Nullable
    public RedisConnectionFactory getConnectionFactory() {
        return this.connectionFactory;
    }

    public RedisConnectionFactory getRequiredConnectionFactory() {
        RedisConnectionFactory connectionFactory = this.getConnectionFactory();
        if (connectionFactory == null) {
            throw new IllegalStateException("RedisConnectionFactory is required");
        } else {
            return connectionFactory;
        }
    }

    public void setConnectionFactory(RedisConnectionFactory connectionFactory) {
        this.connectionFactory = connectionFactory;
    }
}      

三,RedisTemplate

1.序列化配置

RedisTemplate主要關注初始化bean時做了什麼

public void afterPropertiesSet() {
        super.afterPropertiesSet();
        boolean defaultUsed = false;
        if (this.defaultSerializer == null) {
            this.defaultSerializer = new JdkSerializationRedisSerializer(this.classLoader != null ? this.classLoader : this.getClass().getClassLoader());
        }

        if (this.enableDefaultSerializer) {
            if (this.keySerializer == null) {
                this.keySerializer = this.defaultSerializer;
                defaultUsed = true;
            }

            if (this.valueSerializer == null) {
                this.valueSerializer = this.defaultSerializer;
                defaultUsed = true;
            }

            if (this.hashKeySerializer == null) {
                this.hashKeySerializer = this.defaultSerializer;
                defaultUsed = true;
            }

            if (this.hashValueSerializer == null) {
                this.hashValueSerializer = this.defaultSerializer;
                defaultUsed = true;
            }
        }

        if (this.enableDefaultSerializer && defaultUsed) {
            Assert.notNull(this.defaultSerializer, "default serializer null and not all serializers initialized");
        }

        if (this.scriptExecutor == null) {
            this.scriptExecutor = new DefaultScriptExecutor(this);
        }

        this.initialized = true;
    }      

2.連接配接擷取和關閉

@Nullable
    public <T> T execute(RedisCallback<T> action, boolean exposeConnection, boolean pipeline) {
        Assert.isTrue(this.initialized, "template not initialized; call afterPropertiesSet() before using it");
        Assert.notNull(action, "Callback object must not be null");
        RedisConnectionFactory factory = this.getRequiredConnectionFactory();
        RedisConnection conn = null;

        //擷取連接配接從連接配接工廠中
        Object var11;
        try {
            if (this.enableTransactionSupport) {
                conn = RedisConnectionUtils.bindConnection(factory, this.enableTransactionSupport);
            } else {
                conn = RedisConnectionUtils.getConnection(factory);
            }

            boolean existingConnection = TransactionSynchronizationManager.hasResource(factory);
            RedisConnection connToUse = this.preProcessConnection(conn, existingConnection);
            boolean pipelineStatus = connToUse.isPipelined();
            if (pipeline && !pipelineStatus) {
                connToUse.openPipeline();
            }

            RedisConnection connToExpose = exposeConnection ? connToUse : this.createRedisConnectionProxy(connToUse);
            //封裝連接配接,傳入回調函數執行真正的redis操作
            T result = action.doInRedis(connToExpose);
            if (pipeline && !pipelineStatus) {
                connToUse.closePipeline();
            }

            var11 = this.postProcessResult(result, connToUse, existingConnection);
        } finally {
            //釋放連接配接
            RedisConnectionUtils.releaseConnection(conn, factory);
        }

        return var11;
    }      
public Boolean delete(K key) {
        byte[] rawKey = this.rawKey(key);
        Long result = (Long)this.execute((connection) -> {
            return connection.del(new byte[][]{rawKey});
        }, true);
        return result != null && result.intValue() == 1;
    }