動態代理在代碼中的應用

動態代理在代碼中的應用.

先看一段代碼

MixedRedisHelperFactoryBean:

@Component
public class MixedRedisHelperFactoryBean implements FactoryBean<MixedRedisHelper>, InitializingBean, InvocationHandler {

    @Autowired
    private ShardedJedisTemplate shardedJedisTemplate;

    @Autowired
    private JedisClusterTemplate jedisClusterTemplate;

    private MixedRedisHelper helper;


    @Override
    public void afterPropertiesSet() throws Exception {
        helper = (MixedRedisHelper) Proxy.newProxyInstance(MixedRedisHelperFactoryBean.class.getClassLoader(),
                new Class<?>[]{MixedRedisHelper.class}, this);
    }

    @Override
    public MixedRedisHelper getObject() throws Exception {
        return helper;
    }

    @Override
    public Class<?> getObjectType() {
        return MixedRedisHelper.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        }
        Object target;
        //根據開關來決定使用啥shard:cluster
        if (ConfigManager.getBoolean("redis.cluster.standalone", false)) {
            target = jedisClusterTemplate;
        } else {
            target = shardedJedisTemplate;
        }
        return method.invoke(target, args);
    }
}

MixedRedisHelper:

public interface MixedRedisHelper extends JedisCommands {
}

ShardedJedisTemplate:

public interface ShardedJedisTemplate extends JedisCommands, Closeable, BinaryJedisCommands {
	List<?> pipelined(PipelineHandler handler);
}

JedisClusterTemplate:

public interface JedisClusterTemplate extends BasicCommands, BinaryJedisClusterCommands, MultiKeyBinaryJedisClusterCommands,
        JedisClusterBinaryScriptingCommands, JedisCommands, MultiKeyJedisClusterCommands, JedisClusterScriptingCommands {

}

InitializingBean就是一個初始化類需要重寫afterPropertiesSet();就當是@postconstruct;

所以此處的代碼是在類初始化的時候初始化了一個MixedRedisHelperFactoryBean,從它實現FactoryBean可以知道它是用來生成MixedRedisHelper,就是說在使用@Autowired註解使用MixedRedisHelper的時候會使用此Factory生產的MixedRedisHelper的實例。

在來看它的初始方法

  @Override
    public void afterPropertiesSet() throws Exception {
        helper = (MixedRedisHelper) Proxy.newProxyInstance(MixedRedisHelperFactoryBean.class.getClassLoader(),
                new Class<?>[]{MixedRedisHelper.class}, this);
    }

這裏使用了動態代理。。Proxy的用法請google。所以此Factory中的MixedRedisHelper對象是有代理生成的,也即我們執行MixedRedisHelper這個對象實例的時候會執行invoke方法。

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        }
        Object target;
        //根據開關來決定使用啥shard:cluster
        if (ConfigManager.getBoolean("redis.cluster.standalone", false)) {
            target = jedisClusterTemplate;
        } else {
            target = shardedJedisTemplate;
        }
        return method.invoke(target, args);
    }

這裏的invoke又使用了注入JedisClusterTemplate,ShardedJedisTemplate,這樣就達到了通過配置文件來區分使用哪個,其中還有其他的請等等。。

待續!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章