import java.util.Arrays;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.context.support.XmlWebApplicationContext;
/**
* 获取spring 容器的上下文
*
* @author
* @date 2015年5月13日
* @time 下午6:26:48
*/
@Component
@Lazy(false)
@Log4j
public class SpringApplicationContextUtil implements ApplicationContextAware {
//private final Logger logger = LogManager.getLogger(getClass());
private static XmlWebApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext ac) throws BeansException {
applicationContext = (XmlWebApplicationContext)ac;
DefaultListableBeanFactory slbf = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
log.error("ac.getBeanDefinitionNames()");
String [] arr = slbf.getBeanDefinitionNames();
for(String s:arr){
log.error(s);
System.out.println(slbf.getBean(s).getClass());
log.error(Arrays.asList(slbf.getDependentBeans(s)));
log.error(Arrays.asList(slbf.getDependenciesForBean(s)));
System.out.println("----------------------");
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> arg0) {
return getApplicationContext().getBean(arg0);
}
}
有个群友在群里问如何获取到一个容易内所有的bean
查了下源码,其实在
DefaultListableBeanFactory
/** Map from serialized id to factory instance */
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
/** Optional id for this factory, for serialization purposes */
private String serializationId;
/** Whether to allow re-registration of a different definition with the same name */
private boolean allowBeanDefinitionOverriding = true;
/** Whether to allow eager class loading even for lazy-init beans */
private boolean allowEagerClassLoading = true;
/** Resolver to use for checking if a bean definition is an autowire candidate */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/** Map from dependency type to corresponding autowired value */
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
/** Map of singleton and non-singleton bean names keyed by dependency type */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** Map of singleton-only bean names keyed by dependency type */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** List of bean definition names, in registration order */
private final List<String> beanDefinitionNames = new ArrayList<String>();
这里面都有,只是为了保护设置成为了私有的.
不过首先得了解spring的实例化过程
先通过xml配置或者注解解析spring管理的bean 的定义 BeanDefinition
例如依赖谁,是不是单利,是否延迟初始化等.这里就可以找到是否有循环依赖
然后再根据定义实力化bean,并反射设置依赖