|
@@ -0,0 +1,140 @@
|
|
|
+package cn.nosum.framework.context;
|
|
|
+
|
|
|
+import cn.nosum.framework.annotation.Autowired;
|
|
|
+import cn.nosum.framework.annotation.Controller;
|
|
|
+import cn.nosum.framework.annotation.Service;
|
|
|
+import cn.nosum.framework.beans.BeanDefinition;
|
|
|
+import cn.nosum.framework.beans.BeanWrapper;
|
|
|
+import cn.nosum.framework.beans.support.BeanDefinitionReader;
|
|
|
+
|
|
|
+import java.lang.reflect.Field;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Properties;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+
|
|
|
+public class ApplicationContext {
|
|
|
+ protected final Map<String, BeanDefinition> beanDefinitionMap=new ConcurrentHashMap<String, BeanDefinition>();
|
|
|
+ private String[] configLocations;
|
|
|
+ private BeanDefinitionReader reader;
|
|
|
+
|
|
|
+ private Map<String,Object> factoryBeanObjectCache=new ConcurrentHashMap<String, Object>();
|
|
|
+ private Map<String, BeanWrapper> factoryBeanInstanceCache=new ConcurrentHashMap<String, BeanWrapper>();
|
|
|
+
|
|
|
+ public ApplicationContext(String... configLocations){
|
|
|
+ this.configLocations=configLocations;
|
|
|
+ try {
|
|
|
+ // 定位
|
|
|
+ reader=new BeanDefinitionReader(this.configLocations);
|
|
|
+ // 加载配置文件,扫描相关的类,包装为 BeanDefinition
|
|
|
+ List<BeanDefinition>beanDefinitions=reader.loadBeanDefinitions();
|
|
|
+ // 注册,将配置信息放到容器中
|
|
|
+ doRegistryBeanDefinition(beanDefinitions);
|
|
|
+ // 依赖注入
|
|
|
+ doAutowired();
|
|
|
+ }catch (Exception e){e.printStackTrace();}
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doRegistryBeanDefinition(List<BeanDefinition> beanDefinitions) throws Exception {
|
|
|
+ for (BeanDefinition beanDefinition : beanDefinitions) {
|
|
|
+ if (this.beanDefinitionMap.containsKey(beanDefinition.getFactoryBeanName())){
|
|
|
+ throw new Exception("The Bean " + beanDefinition.getFactoryBeanName() + "is exists!!");
|
|
|
+ }
|
|
|
+ this.beanDefinitionMap.put(beanDefinition.getFactoryBeanName(),beanDefinition);
|
|
|
+ this.beanDefinitionMap.put(beanDefinition.getBeanClassName(),beanDefinition);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void doAutowired() {
|
|
|
+ for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : this.beanDefinitionMap.entrySet()) {
|
|
|
+ String beanName=beanDefinitionEntry.getKey();
|
|
|
+ try {
|
|
|
+ getBean(beanName);
|
|
|
+ }catch (Exception e){e.printStackTrace();}
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Object getBean(Class<?> beanClass) {
|
|
|
+ return getBean(beanClass.getName());
|
|
|
+ }
|
|
|
+
|
|
|
+ private Object getBean(String beanName) {
|
|
|
+ // 读取配置信息
|
|
|
+ BeanDefinition beanDefinition=this.beanDefinitionMap.get(beanName);
|
|
|
+ // 将对象封装到 BeanDefinitionWrapper 中
|
|
|
+ BeanWrapper beanWrapper=new BeanWrapper(instantiateBean(beanDefinition));
|
|
|
+ // 缓存
|
|
|
+ this.factoryBeanInstanceCache.put(beanName,beanWrapper);
|
|
|
+ // 依赖注入
|
|
|
+ populateBean(beanName,beanDefinition,beanWrapper);
|
|
|
+ return this.factoryBeanInstanceCache.get(beanName).getWrapperInstance();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void populateBean(String beanName, BeanDefinition beanDefinition, BeanWrapper beanWrapper) {
|
|
|
+ //可能涉及到循环依赖?
|
|
|
+ //A{ B b}
|
|
|
+ //B{ A b}
|
|
|
+ //用两个缓存,循环两次
|
|
|
+ //1、把第一次读取结果为空的BeanDefinition存到第一个缓存
|
|
|
+ //2、等第一次循环之后,第二次循环再检查第一次的缓存,再进行赋值
|
|
|
+ Object instance = beanWrapper.getWrapperInstance();
|
|
|
+ Class<?> clazz = beanWrapper.getWrappedClass();
|
|
|
+ //在Spring中@Component
|
|
|
+ if(!(clazz.isAnnotationPresent(Controller.class) || clazz.isAnnotationPresent(Service.class))){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //把所有的包括private/protected/default/public 修饰字段都取出来
|
|
|
+ for (Field field : clazz.getDeclaredFields()) {
|
|
|
+ if(!field.isAnnotationPresent(Autowired.class)){ continue; }
|
|
|
+ Autowired autowired = field.getAnnotation(Autowired.class);
|
|
|
+ //如果用户没有自定义的beanName,就默认根据类型注入
|
|
|
+ String autowiredBeanName = autowired.value().trim();
|
|
|
+ if("".equals(autowiredBeanName)){
|
|
|
+ //field.getType().getName() 获取字段的类型
|
|
|
+ autowiredBeanName = field.getType().getName();
|
|
|
+ }
|
|
|
+ //暴力访问
|
|
|
+ field.setAccessible(true);
|
|
|
+ try {
|
|
|
+ if(this.factoryBeanInstanceCache.get(autowiredBeanName) == null){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ field.set(instance,this.factoryBeanInstanceCache.get(autowiredBeanName).getWrapperInstance());
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private Object instantiateBean(BeanDefinition beanDefinition) {
|
|
|
+ // 取得实例化对象的类名
|
|
|
+ String className=beanDefinition.getBeanClassName();
|
|
|
+ Object instance=null;
|
|
|
+ try{
|
|
|
+ if (this.factoryBeanObjectCache.containsKey(className)){
|
|
|
+ instance=this.factoryBeanObjectCache.get(className);
|
|
|
+ }else{
|
|
|
+ Class<?> clazz=Class.forName(className);
|
|
|
+ instance=clazz.getDeclaredConstructor().newInstance();
|
|
|
+ this.factoryBeanObjectCache.put(className,instance);
|
|
|
+ this.factoryBeanObjectCache.put(beanDefinition.getFactoryBeanName(),instance);
|
|
|
+ }
|
|
|
+ }catch (Exception e){e.printStackTrace();}
|
|
|
+ return instance;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String[] getBeanDefinitionNames(){
|
|
|
+ return this.beanDefinitionMap.keySet().toArray(new String[getBeanDefinitionCount()]);
|
|
|
+ }
|
|
|
+
|
|
|
+ public int getBeanDefinitionCount(){
|
|
|
+ return this.beanDefinitionMap.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ public Properties getConfig(){
|
|
|
+ return this.reader.getConfig();
|
|
|
+ }
|
|
|
+
|
|
|
+}
|