多品牌网站建设,大型商城网站建设方案,2022app分类排行,怎么看网站是服务器还是虚拟主机概述
模拟大致的底层原理#xff0c;为学习Spring源码做铺垫。
实现的功能#xff1a;扫描路径、依赖注入、aware回调、初始化前、初始化、初始化后、切面
未实现的功能#xff1a;构造器推断、循环依赖
重点#xff1a;BeanDefinition、BeanPostProcessor
学习Spring…概述
模拟大致的底层原理为学习Spring源码做铺垫。
实现的功能扫描路径、依赖注入、aware回调、初始化前、初始化、初始化后、切面
未实现的功能构造器推断、循环依赖
重点BeanDefinition、BeanPostProcessor
学习Spring源码的重点设计模式、编码规范、设计思想、扩展点 启动类
public class Yeah
{public static void main(String[] args){GaxApplicationContext gaxApplicationContext new GaxApplicationContext(AppConfig.class);UserInterface userService (UserInterface) gaxApplicationContext.getBean(userService);userService.test();}
}
关键方法
public class GaxApplicationContext
{private Class configClass;private static final String SINGLETON singleton;private MapString, BeanDefinition beanDefinitionMap new HashMap();private MapString, Object singletonObjects new HashMap();// Spring源码用的是LinkedListprivate ListBeanPostProcessor beanPostProcessorList new ArrayList();public GaxApplicationContext(Class configClass){this.configClass configClass;// 扫描指定路径找到所有Component注解的类封装成beanDefinition保存再Map中scan(configClass);// 思考个问题beanDefinitionMap.keySet()和beanDefinitionMap.entrySet()两种遍历的区别选用哪个好for (Map.EntryString, BeanDefinition entry : beanDefinitionMap.entrySet()){String beanName entry.getKey();BeanDefinition beanDefinition entry.getValue();if (SINGLETON.equals(beanDefinition.getScope())){Object bean createBean(beanName, beanDefinition);singletonObjects.put(beanName, bean);}}}private Object createBean(String beanName, BeanDefinition beanDefinition){Class clazz beanDefinition.getType();Object instance null;try{// 直接使用默认的无参构造器多个构造器的场景未实现instance clazz.getConstructor().newInstance();// 属性填充依赖注入for (Field field : clazz.getDeclaredFields()){if (field.isAnnotationPresent(Autowired.class)){field.setAccessible(true);field.set(instance, getBean(field.getName()));}}// aware回调if (instance instanceof BeanNameAware){((BeanNameAware)instance).setBeanName(beanName);}// 初始化前for (BeanPostProcessor beanPostProcessor : beanPostProcessorList){instance beanPostProcessor.postProcessBeforeInitialization(instance, beanName);}// 初始化if (instance instanceof InitializingBean){((InitializingBean)instance).afterPropertiesSet();}// 初始化后for (BeanPostProcessor beanPostProcessor : beanPostProcessorList){instance beanPostProcessor.postProcessAfterInitialization(instance, beanName);}}catch (InstantiationException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e){e.printStackTrace();}return instance;}public Object getBean(String beanName){if (!beanDefinitionMap.containsKey(beanName)){throw new NullPointerException();}BeanDefinition beanDefinition beanDefinitionMap.get(beanName);if (SINGLETON.equals(beanDefinition.getScope())){Object singletonBean singletonObjects.get(beanName);if (null singletonBean){singletonBean createBean(beanName, beanDefinition);singletonObjects.put(beanName, singletonBean);}return singletonBean;}else{// 原型BeanObject prototypeBean createBean(beanName, beanDefinition);return prototypeBean;}}private void scan(Class configClass){if (configClass.isAnnotationPresent(ComponentScan.class)){ComponentScan componentScanAnnotation (ComponentScan)configClass.getAnnotation(ComponentScan.class);String path componentScanAnnotation.value();// path com/gax/servicepath path.replace(., /);ClassLoader classLoader GaxApplicationContext.class.getClassLoader();URL resource classLoader.getResource(path);assert resource ! null;File file new File(resource.getFile());if (file.isDirectory()){for (File f : Objects.requireNonNull(file.listFiles())){String absolutePath f.getAbsolutePath();absolutePath absolutePath.substring(absolutePath.indexOf(com), absolutePath.indexOf(.class));// 类加载器入参需要的格式com.gax.service.XXXabsolutePath absolutePath.replace(\\, .);try{Class? clazz classLoader.loadClass(absolutePath);if (clazz.isAnnotationPresent(Component.class)){if (BeanPostProcessor.class.isAssignableFrom(clazz)){BeanPostProcessor instance (BeanPostProcessor)clazz.getConstructor().newInstance();beanPostProcessorList.add(instance);}Component componentAnnotation clazz.getAnnotation(Component.class);String beanName componentAnnotation.value();if (.equals(beanName)){// 默认beanNamebeanName Introspector.decapitalize(clazz.getSimpleName());}BeanDefinition beanDefinition new BeanDefinition();beanDefinition.setType(clazz);if (clazz.isAnnotationPresent(Scope.class)){Scope scopeAnnotation clazz.getAnnotation(Scope.class);String value scopeAnnotation.value();beanDefinition.setScope(value);}else{// 默认单例BeanbeanDefinition.setScope(SINGLETON);}beanDefinitionMap.put(beanName, beanDefinition);}}catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException| InstantiationException | IllegalAccessException e){e.printStackTrace();}}}}}
}
gitee地址
git clone https://gitee.com/seek6174/spring-seek.git