package com.baidu.disconf.client.support.registry.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.baidu.disconf.client.support.registry.Registry;
/**
* Created by knightliao on 15/11/26.
*/
public class SpringRegistry implements Registry, ApplicationContextAware {
protected static final Logger LOGGER = LoggerFactory.getLogger(SpringRegistry.class);
// Spring应用上下文环境
private static ApplicationContext applicationContext;
private SimpleRegistry simpleRegistry = new SimpleRegistry();
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public <T> List<T> findByType(Class<T> type, boolean newInstance) {
if (applicationContext == null) {
LOGGER.error("Spring Context is null. Cannot autowire " + type.getCanonicalName());
return new ArrayList<T>(0);
}
if (type == null) {
return new ArrayList<T>(0);
}
Map<String, T> map = findByTypeWithName(type);
if (map == null || map.isEmpty()) {
if (newInstance) {
LOGGER.debug("Not found from Spring IoC container for " + type.getSimpleName() + ", and try to init by "
+ "calling newInstance.");
return simpleRegistry.findByType(type, newInstance);
}
}
return new ArrayList<T>(map.values());
}
@Override
public <T> T getFirstByType(Class<T> type, boolean newInstance) {
List<T> list = this.findByType(type, newInstance);
if (list.size() == 0) {
return null;
}
return list.get(0);
}
@Override
public <T> T getFirstByType(Class<T> type, boolean newInstance, boolean withProxy) {
T object = getFirstByType(type, newInstance);
if (!withProxy) {
return object;
}
try {
return getTargetObject(object, type);
} catch (Exception e) {
LOGGER.warn(e.toString());
return object;
}
}
/**
* 调用Spring工具类获取bean
*
* @param type 类类型
*
* @return 容器托管的bean字典
*/
public <T> Map<String, T> findByTypeWithName(Class<T> type) {
return applicationContext.getBeansOfType(type);
}
protected <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception {
if (AopUtils.isJdkDynamicProxy(proxy)) {
return (T) ((Advised) proxy).getTargetSource().getTarget();
} else if (AopUtils.isCglibProxy(proxy)) {
return (T) ((Advised) proxy).getTargetSource().getTarget();
} else {
return (T) proxy;
}
}
}