ApplicationContext.java 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package cn.nosum.framework.context;
  2. import cn.nosum.framework.annotation.Autowired;
  3. import cn.nosum.framework.annotation.Controller;
  4. import cn.nosum.framework.annotation.Service;
  5. import cn.nosum.framework.beans.BeanDefinition;
  6. import cn.nosum.framework.beans.BeanWrapper;
  7. import cn.nosum.framework.beans.support.BeanDefinitionReader;
  8. import java.lang.reflect.Field;
  9. import java.util.List;
  10. import java.util.Map;
  11. import java.util.Properties;
  12. import java.util.concurrent.ConcurrentHashMap;
  13. public class ApplicationContext {
  14. protected final Map<String, BeanDefinition> beanDefinitionMap=new ConcurrentHashMap<String, BeanDefinition>();
  15. private String[] configLocations;
  16. private BeanDefinitionReader reader;
  17. private Map<String,Object> factoryBeanObjectCache=new ConcurrentHashMap<String, Object>();
  18. private Map<String, BeanWrapper> factoryBeanInstanceCache=new ConcurrentHashMap<String, BeanWrapper>();
  19. public ApplicationContext(String... configLocations){
  20. this.configLocations=configLocations;
  21. try {
  22. // 定位
  23. reader=new BeanDefinitionReader(this.configLocations);
  24. // 加载配置文件,扫描相关的类,包装为 BeanDefinition
  25. List<BeanDefinition>beanDefinitions=reader.loadBeanDefinitions();
  26. // 注册,将配置信息放到容器中
  27. doRegistryBeanDefinition(beanDefinitions);
  28. // 依赖注入
  29. doAutowired();
  30. }catch (Exception e){e.printStackTrace();}
  31. }
  32. private void doRegistryBeanDefinition(List<BeanDefinition> beanDefinitions) throws Exception {
  33. for (BeanDefinition beanDefinition : beanDefinitions) {
  34. if (this.beanDefinitionMap.containsKey(beanDefinition.getFactoryBeanName())){
  35. throw new Exception("The Bean " + beanDefinition.getFactoryBeanName() + "is exists!!");
  36. }
  37. this.beanDefinitionMap.put(beanDefinition.getFactoryBeanName(),beanDefinition);
  38. this.beanDefinitionMap.put(beanDefinition.getBeanClassName(),beanDefinition);
  39. }
  40. }
  41. private void doAutowired() {
  42. for (Map.Entry<String, BeanDefinition> beanDefinitionEntry : this.beanDefinitionMap.entrySet()) {
  43. String beanName=beanDefinitionEntry.getKey();
  44. try {
  45. getBean(beanName);
  46. }catch (Exception e){e.printStackTrace();}
  47. }
  48. }
  49. private Object getBean(Class<?> beanClass) {
  50. return getBean(beanClass.getName());
  51. }
  52. private Object getBean(String beanName) {
  53. // 读取配置信息
  54. BeanDefinition beanDefinition=this.beanDefinitionMap.get(beanName);
  55. // 将对象封装到 BeanDefinitionWrapper 中
  56. BeanWrapper beanWrapper=new BeanWrapper(instantiateBean(beanDefinition));
  57. // 缓存
  58. this.factoryBeanInstanceCache.put(beanName,beanWrapper);
  59. // 依赖注入
  60. populateBean(beanName,beanDefinition,beanWrapper);
  61. return this.factoryBeanInstanceCache.get(beanName).getWrapperInstance();
  62. }
  63. private void populateBean(String beanName, BeanDefinition beanDefinition, BeanWrapper beanWrapper) {
  64. //可能涉及到循环依赖?
  65. //A{ B b}
  66. //B{ A b}
  67. //用两个缓存,循环两次
  68. //1、把第一次读取结果为空的BeanDefinition存到第一个缓存
  69. //2、等第一次循环之后,第二次循环再检查第一次的缓存,再进行赋值
  70. Object instance = beanWrapper.getWrapperInstance();
  71. Class<?> clazz = beanWrapper.getWrappedClass();
  72. //在Spring中@Component
  73. if(!(clazz.isAnnotationPresent(Controller.class) || clazz.isAnnotationPresent(Service.class))){
  74. return;
  75. }
  76. //把所有的包括private/protected/default/public 修饰字段都取出来
  77. for (Field field : clazz.getDeclaredFields()) {
  78. if(!field.isAnnotationPresent(Autowired.class)){ continue; }
  79. Autowired autowired = field.getAnnotation(Autowired.class);
  80. //如果用户没有自定义的beanName,就默认根据类型注入
  81. String autowiredBeanName = autowired.value().trim();
  82. if("".equals(autowiredBeanName)){
  83. //field.getType().getName() 获取字段的类型
  84. autowiredBeanName = field.getType().getName();
  85. }
  86. //暴力访问
  87. field.setAccessible(true);
  88. try {
  89. if(this.factoryBeanInstanceCache.get(autowiredBeanName) == null){
  90. continue;
  91. }
  92. field.set(instance,this.factoryBeanInstanceCache.get(autowiredBeanName).getWrapperInstance());
  93. } catch (IllegalAccessException e) {
  94. e.printStackTrace();
  95. continue;
  96. }
  97. }
  98. }
  99. private Object instantiateBean(BeanDefinition beanDefinition) {
  100. // 取得实例化对象的类名
  101. String className=beanDefinition.getBeanClassName();
  102. Object instance=null;
  103. try{
  104. if (this.factoryBeanObjectCache.containsKey(className)){
  105. instance=this.factoryBeanObjectCache.get(className);
  106. }else{
  107. Class<?> clazz=Class.forName(className);
  108. instance=clazz.getDeclaredConstructor().newInstance();
  109. this.factoryBeanObjectCache.put(className,instance);
  110. this.factoryBeanObjectCache.put(beanDefinition.getFactoryBeanName(),instance);
  111. }
  112. }catch (Exception e){e.printStackTrace();}
  113. return instance;
  114. }
  115. public String[] getBeanDefinitionNames(){
  116. return this.beanDefinitionMap.keySet().toArray(new String[getBeanDefinitionCount()]);
  117. }
  118. public int getBeanDefinitionCount(){
  119. return this.beanDefinitionMap.size();
  120. }
  121. public Properties getConfig(){
  122. return this.reader.getConfig();
  123. }
  124. }