Spring-Bean的构造函数和Setter执行顺序以及InitializingBean

时间:2022-07-31 19:26:50


经过试验得知,Spring注入Bean,实例化一个Bean的时候,顺序如下:

1. 这个class的构造函数被执行;

2.Setter被执行;

3.如果这个class实现了InitializingBean(即implements InitializingBean)则,接下来执行public void afterPropertiesSet() throws Exception() 中的内容。



实例,

当我不用InitializingBean 方法,而是直接在构造器中知己执行jedis = jedisPool.getResource();  则因为此时程序只是执行到上面的第1步,这时候jedisPool==null,那这里肯定会报错。会导致RedisClient实例化失败,并且抛出NullPointerException

下面贴上错误的代码。注意这里对RedisClient进行了Spring的Setter注入。

package com.foundjet.flylib.redis;

import java.util.ArrayList;
import java.util.List;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.JedisShardInfo;

public class RedisClient {
	private Jedis jedis;//非切片额客户端连接  
    private JedisPool jedisPool;//非切片连接池  
    private ShardedJedis shardedJedis;//切片额客户端连接  
    private ShardedJedisPool shardedJedisPool;//切片连接池  
    
    private String password = "tea@fjdev";
      
    public RedisClient()   
    {   
        initialPool();   
//        initialShardedPool();   
        jedis = jedisPool.getResource();  
        jedis.auth(password);
        jedis.select(10);
//      shardedJedis = shardedJedisPool.getResource();       
    }   
   
    /** 
     * 初始化非切片池 
     */  
    private void initialPool()   
    {   
        // 池基本配置   
        JedisPoolConfig config = new JedisPoolConfig();   
//        config.setMaxActive(20); 
        config.setMaxTotal(20);
        config.setMaxIdle(5);   
        config.setMaxWaitMillis(1000L);   
        config.setTestOnBorrow(false);   
          
        jedisPool = new JedisPool(config, "127.0.0.1", 6379);  
    }  
      
    /**  
     * 初始化切片池  
     */   
    private void initialShardedPool()   
    {   
        // 池基本配置   
        JedisPoolConfig config = new JedisPoolConfig();   
//        config.setMaxActive(20); 
        config.setMaxTotal(20);
        config.setMaxIdle(5);   
        config.setMaxWaitMillis(1000l);   
        config.setTestOnBorrow(false);   
        // slave链接   
        List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();   
        shards.add(new JedisShardInfo("127.0.0.1", 6379, "master"));   
        
        // 构造池   
        shardedJedisPool = new ShardedJedisPool(config, shards);   
    }   
  
    public void show() {       
        keyOperate();   
        
//        StringOperate();   
//        ListOperate();   
//        SetOperate();  
//        SortedSetOperate();  
//        HashOperate();   
        jedis.close();
//        shardedJedis.close();
    }   
    
    private void keyOperate() {
    	String k = "key3";
    	jedis.set(k, "ccc");
    	System.out.println("value of " + k + " is: "  + jedis.get(k));
    }
    
	public static void main(String[] args) {
		RedisClient client = new RedisClient();
		client.show();
	}
}

修正后的代码见 https://github.com/flylib/rediskit

RedisClient.java

片段如下

package net.flylib.rediskit;

import org.springframework.beans.factory.InitializingBean;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Protocol;

public class RedisClient implements InitializingBean {
	private Jedis jedis;// 非切片额客户端连接
	private JedisPool jedisPool;// 非切片连接池

	public RedisClient() {
//		jedis = jedisPool.getResource();
	}
	
	@Override 
	public void afterPropertiesSet() throws Exception {
		jedis = jedisPool.getResource();
	}

	public JedisPool getJedisPool() {
		return jedisPool;
	}

	public void setJedisPool(JedisPool jedisPool) {
		this.jedisPool = jedisPool;
	}

	public String set(final String key, String value) {
		jedis.get("");
		return jedis.set(key, value);
	}

	public String get(final String key) {
		return jedis.get(key);
	}
}