動態代理在代碼中的應用.
先看一段代碼
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,這樣就達到了通過配置文件來區分使用哪個,其中還有其他的請等等。。
待續!