当前位置: 首页 > news >正文

淮南做网站的公司宁波网站建设公司信息查询

淮南做网站的公司,宁波网站建设公司信息查询,装修公司网站如何做网络推广,ps海报素材网站文章目录 模拟Spring底层详解1、结合配置类#xff0c;扫描类资源1.1、创建需要扫描的配置类AppConfig#xff0c;如下#xff1a;1.2、创建Spring容器对象LyfApplicationContext#xff0c;如下1.3、Spring容器对象LyfApplicationContext扫描资源 2、结合上一步的扫描扫描类资源1.1、创建需要扫描的配置类AppConfig如下1.2、创建Spring容器对象LyfApplicationContext如下1.3、Spring容器对象LyfApplicationContext扫描资源 2、结合上一步的扫描遍历其Map集合创建对象3、创建对象后需要提供需要获取Bean的方法4、总结 模拟Spring底层详解 前置准备创建部分注解具体如下 /*** 依赖注入注解信息*/ Retention(RetentionPolicy.RUNTIME) Target(ElementType.FIELD) public interface Autowired { }/*** 自定义一个注解是为了标识使用此注解之处的类资源需要交给Spring容器管理* 可自定义beanName*/ Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) public interface Component {String value() default ; }/*** 定于扫描类bean资源路径*/ Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) public interface ComponentScan {String value() default ; }Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) public interface Scope {String value() default ; } 两个service类用于测试 Component Scope() public class OrderService { }Component public class UserService {private String name;Autowiredprivate OrderService orderService;public void testDemo(){System.out.println(Spring 创建 userService 实例成功);System.out.println(Spring 依赖注入 orderService 实例对象orderService);} }一个测试类 public class TestSpringDemo {public static void main(String[] args) throws Exception{LyfApplicationContext context new LyfApplicationContext(AppConfig.class);UserService userService (UserService) context.getBean(userService);userService.testDemo();} }1、结合配置类扫描类资源 Spring在创建对象前需要去扫描确定需要交给Spring管理的类资源具体的实现步骤模拟代码如下 1.1、创建需要扫描的配置类AppConfig如下 /*** 这个类主要是用于定义扫描资源的路径信息*/ ComponentScan(com.practice.service) public class AppConfig { }1.2、创建Spring容器对象LyfApplicationContext如下 /*** 这个类主要是用于模拟Spring容器的bean的创建与获取bean等*/ public class LyfApplicationContext {public LyfApplicationContext(Class config) throws Exception{}}1.3、Spring容器对象LyfApplicationContext扫描资源 在LyfApplicationContext容器含参构造中需要结合传入扫描资源的配置类AppConfig对资源进行扫描具体实现代码如下 /*** 这个类主要是用于模拟Spring容器的bean的创建与获取bean等*/ public class LyfApplicationContext {public LyfApplicationContext(Class config) throws Exception{//判断传入的config类上是否有componentScan注解if (config.isAnnotationPresent(ComponentScan.class)) {//1、获取传入类上的注解ComponentScan信息主要是获取扫描路径ComponentScan componentScanAnnotation (ComponentScan) config.getAnnotation(ComponentScan.class);//2、获取注解中的值String path componentScanAnnotation.value();//3、将注解中的值.换为/path path.replace(.,/);//4、结合当前容器的类加载器加载路径path下的class资源//4.1 先获取当前容器的类加载器ClassLoader classLoader LyfApplicationContext.class.getClassLoader();//4.2 利用上一步获取的类加载器获取path路径下的class文件资源url信息URL resource classLoader.getResource(path); //D:/JavaWorkSpace/2023/spring/spring-study-demo01/target/classes/com/practice/service//4.3 获取当前resource路径下的文件资源信息File file new File(resource.getFile());//4.4 遍历file文件数据获取file下的所有class文件资源if (file.isDirectory()) {for (File f : file.listFiles()) {String absolutePath f.getAbsolutePath(); //获取到class资源的绝对路径信息目的是为了加载此类信息// 4.4.1 将此类的绝对路径做处理截取一部分absolutePath absolutePath.substring(absolutePath.indexOf(com),absolutePath.indexOf(.class)).replace(\\,.);//com.practice.service.UserService//4.4.2 用上述得到的类加载器加载上述的absolutePath路径下的class资源信息目的是为了检查当前遍历的class资源上是否包含Component注解try{Class? clazz classLoader.loadClass(absolutePath);// 如果当前的对象实现了beanPostProcessor接口需要将其加入beanPostProcessorList集合中if (BeanPostProcessor.class.isAssignableFrom(clazz)) {BeanPostProcessor instance (BeanPostProcessor) clazz.getConstructor().newInstance();beanPostProcessorList.add(instance);}if (clazz.isAnnotationPresent(Component.class)) {//创建一个BeanDefinition对象用于保存每个类的特征BeanDefinition beanDefinition new BeanDefinition();beanDefinition.setType(clazz);//4.4.2.1 获取当前注解Component的值之定义的beanNameComponent annotation clazz.getAnnotation(Component.class);String beanName annotation.value();//如果当前传入的beanName为空的话利用默认的也就是类名首字母小写作为beanNameif (.equals(beanName)) {beanName Introspector.decapitalize(clazz.getSimpleName());}//4.4.2.2 除此之外还需要判断是否有Scope注解主要是判断当前的bean是否是单例或者是原型的if (clazz.isAnnotationPresent(Scope.class)) {//获取注解中的值Scope scopeAnnotation clazz.getAnnotation(Scope.class);String value scopeAnnotation.value();beanDefinition.setScope(value);}else {beanDefinition.setScope(singleton);}//将封装好的beanDefinition缓存到Map中beanDefinitionMap.put(beanName,beanDefinition);}}catch (Exception e){throw new Exception(absolutePath 类加载失败,e);}}}}else {throw new Exception(缺少路径资源配置信息~~~);}} }其过程如下 先结合传入扫描资源的配置类AppConfig类上是否包含注解ComponentScan若包含注解需要获取其注解中的参数信息配置的扫描包路径获取当前资源的类加载器目的是为了获取target包下的class资源信息获取到指定包路径下的class资源利用其构造方法创建对象对对象中的属性以及对象上加入的注解信息进行遍历扫描进行相关的逻辑处理将其类元信息加入到BeanDefinition对象中再将其封装为一个Map对象在接下来的对象创建与获取的过程中做好基奠其对象信息就是记录每一个类的特征部分代码如下 /*** 这个类主要是去记录下描述一个bean的特征*/ public class BeanDefinition {//类的类型private Class type;//创建类的方式单例还是原型等private String scope;public Class getType() {return type;}public void setType(Class type) {this.type type;}public String getScope() {return scope;}public void setScope(String scope) {this.scope scope;} }2、结合上一步的扫描遍历其Map集合创建对象 /*** 这个类主要是用于模拟Spring容器的bean的创建与获取bean等*/ public class LyfApplicationContext {public LyfApplicationContext(Class config) throws Exception{//判断传入的config类上是否有componentScan注解if (config.isAnnotationPresent(ComponentScan.class)) {//1、获取传入类上的注解ComponentScan信息主要是获取扫描路径ComponentScan componentScanAnnotation (ComponentScan) config.getAnnotation(ComponentScan.class);//2、获取注解中的值String path componentScanAnnotation.value();//3、将注解中的值.换为/path path.replace(.,/);//4、结合当前容器的类加载器加载路径path下的class资源//4.1 先获取当前容器的类加载器ClassLoader classLoader LyfApplicationContext.class.getClassLoader();//4.2 利用上一步获取的类加载器获取path路径下的class文件资源url信息URL resource classLoader.getResource(path); //D:/JavaWorkSpace/2023/spring/spring-study-demo01/target/classes/com/practice/service//4.3 获取当前resource路径下的文件资源信息File file new File(resource.getFile());//4.4 遍历file文件数据获取file下的所有class文件资源if (file.isDirectory()) {for (File f : file.listFiles()) {String absolutePath f.getAbsolutePath(); //获取到class资源的绝对路径信息目的是为了加载此类信息// 4.4.1 将此类的绝对路径做处理截取一部分absolutePath absolutePath.substring(absolutePath.indexOf(com),absolutePath.indexOf(.class)).replace(\\,.);//com.practice.service.UserService//4.4.2 用上述得到的类加载器加载上述的absolutePath路径下的class资源信息目的是为了检查当前遍历的class资源上是否包含Component注解try{Class? clazz classLoader.loadClass(absolutePath);// 如果当前的对象实现了beanPostProcessor接口需要将其加入beanPostProcessorList集合中if (BeanPostProcessor.class.isAssignableFrom(clazz)) {BeanPostProcessor instance (BeanPostProcessor) clazz.getConstructor().newInstance();beanPostProcessorList.add(instance);}if (clazz.isAnnotationPresent(Component.class)) {//创建一个BeanDefinition对象用于保存每个类的特征BeanDefinition beanDefinition new BeanDefinition();beanDefinition.setType(clazz);//4.4.2.1 获取当前注解Component的值之定义的beanNameComponent annotation clazz.getAnnotation(Component.class);String beanName annotation.value();//如果当前传入的beanName为空的话利用默认的也就是类名首字母小写作为beanNameif (.equals(beanName)) {beanName Introspector.decapitalize(clazz.getSimpleName());}//4.4.2.2 除此之外还需要判断是否有Scope注解主要是判断当前的bean是否是单例或者是原型的if (clazz.isAnnotationPresent(Scope.class)) {//获取注解中的值Scope scopeAnnotation clazz.getAnnotation(Scope.class);String value scopeAnnotation.value();beanDefinition.setScope(value);}else {beanDefinition.setScope(singleton);}//将封装好的beanDefinition缓存到Map中beanDefinitionMap.put(beanName,beanDefinition);}}catch (Exception e){throw new Exception(absolutePath 类加载失败,e);}}}}else {throw new Exception(缺少路径资源配置信息~~~);}}//创建对象for (Map.EntryString, BeanDefinition definitionEntry : beanDefinitionMap.entrySet()) {//获取BeanDefinitionMap中的key和valueString beanName definitionEntry.getKey();BeanDefinition definition definitionEntry.getValue();//判断当前的BeanDefinition对象是否是单例if (singleton.equals(definition.getScope())) {Object bean creatBean(beanName, definition);singletonMap.put(beanName,bean);}}/*** 创建bean对象* param beanName bean名称* param definition 对象描述封装类* return* throws Exception*/public Object creatBean(String beanName, BeanDefinition definition) throws Exception {//创建当前对象且放入单例池中单例的Map中Class clazz definition.getType();try {Object instance clazz.getConstructor().newInstance();//判断当前的对象中是否有autowide依赖注入注解 ,如果包含这个注解需要将其字段进行赋值for (Field field : clazz.getDeclaredFields()) {if (field.isAnnotationPresent(Autowired.class)) {field.setAccessible(true);field.set(instance, getBean(field.getName()));}}//回到方法beanNameAwareif (instance instanceof BeanNameAware) {((BeanNameAware) instance).setBeanName(beanName);}//初始化前方法if (beanPostProcessorList.size() 0) {for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {instance beanPostProcessor.postProcessBeforeInitialization(instance, beanName);}}//初始化if (instance instanceof InitializingBean) {((InitializingBean) instance).afterPropertiesSet();}//初始化后切面AOPif (beanPostProcessorList.size() 0) {for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {instance beanPostProcessor.postProcessAfterInitialization(instance, beanName);}}return instance;} catch (Exception e){throw new Exception(创建对象失败~~~,e);}} } 3、创建对象后需要提供需要获取Bean的方法 /*** 定于一个方法是获取bean资源的*/public Object getBean(String beanName) throws Exception {//判断当前的BeanDefinitionMap中是否存在beanName为key的beanDefinitionif (!beanDefinitionMap.containsKey(beanName)) {throw new Exception(当前beanName在BeanDefinitionMap中不存在~~~);}//从BeanDefinitionMap中获取到BeanDefinition信息判断其scopeBeanDefinition beanDefinition beanDefinitionMap.get(beanName);//单例if (singleton.equals(beanDefinition.getScope())) {Object singletonBean singletonMap.get(beanName);if (singletonBean null) {singletonBean creatBean(beanName,beanDefinition);singletonMap.put(beanName,singletonBean);}return singletonBean;}else {//原型Object prototypeBean creatBean(beanName,beanDefinition);return prototypeBean;}}4、总结 总的来说在Spring创建对象的过程中主要分为结合传入的类路径信息扫描需要创建的对象资源结合上一步的扫描结果创建对象将创建好的对象提供一个对外获取Bean接口具体详细过程图示
http://www.sczhlp.com/news/166650/

相关文章:

  • 国内建筑网站网站开发支付宝支付
  • 深圳做网站联雅北京知名的品牌设计公司
  • 校园网站建设整改建议wordpress add_action 是什么意思
  • 文山文山市网站建设0592 网站建设
  • 建设房地产法律网站建设工程服务中心是做什么的
  • 广州免费建站排行建设个人网银登录
  • 做网站优化的关键词怎么设置实战直播
  • 建设网站如果赚钱怎么查icp备案号
  • 【VM虚拟机】VM新版本,虚拟机中键盘输入延迟卡顿
  • 42区 网站开发指南中英文网站源码
  • 建立网站建站程序简单的网页制作模板
  • 手机端网站开发价格神起网络游戏推广平台
  • 云虚拟主机搭建网站wordpress4 摘要
  • 常德公司做网站商城网站建设浩森宇特
  • DW网站建设出现哪些问题网站运营seo
  • 移动端网站 优帮云企业网站免费认证
  • 西安网站推广方案wordpress ajax 分页插件
  • 精神文明建设专题网站优秀网视频剪辑
  • 建设交通职业技术学院招聘信息网站网站目录结构改变
  • 网站登记备案 个人动漫制作专业主修课程
  • 建设部职称证书查询官方网站成都建设招标网站首页
  • 教育网站制作公司用jsp做网站一般会用到什么软件
  • 企业网站设计源代码磁力链搜索引擎入口
  • dw怎么做jsp网站wordpress pdf view
  • asp.net网站项目站长之家素材
  • 搜狗站长平台打不开怎么做网站淘宝转换工具
  • 东莞市工程建设安监站网站卡片式网站
  • 学院的网站怎么做wordpress电子商城
  • 网站实现步骤及方法网站开发个人总结
  • 华为云Flexus+DeepSeek征文|华为云Flexus服务器dify高效的平台通过自然语言转sql并执行搭建电商数据分析