实现SpringMVC底层机制(二)

这篇具有很好参考价值的文章主要介绍了实现SpringMVC底层机制(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 动态获取spring配置文件

1.修改SunWebApplicationContext.java

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc

2.修改SunDispatcherServlet.java

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc

2.自定义Service注解

1.需求分析

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc

2.编写Monster.java
package com.Sun.entity;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class Monster {
    private Integer id;
    private String name;
    private String skill;
    private Integer age;

    public Monster(Integer id, String name, String skill, Integer age) {
        this.id = id;
        this.name = name;
        this.skill = skill;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", skill='" + skill + '\'' +
                ", age=" + age +
                '}';
    }
}

3.自定义Service注解
package com.Sun.sunspringmvc.annotation;

import java.lang.annotation.*;

/**
 * 自定义注解,用于标识一个service
 *
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.TYPE) //作用于目标是类
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface Service {
    String value() default "";
}

4.编写Service接口MonsterService.java
package com.Sun.sunspringmvc.annotation;

import java.lang.annotation.*;

/**
 * 自定义注解,用于标识一个service
 *
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.TYPE) //作用于目标是类
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface Service {
}

5.编写Service实现类MonsterServiceImpl.java
package com.Sun.service.Impl;

import com.Sun.entity.Monster;
import com.Sun.service.MonsterService;
import com.Sun.sunspringmvc.annotation.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 孙显圣
 * @version 1.0
 */
@Service
public class MonsterServiceImpl implements MonsterService {
    public List<Monster> listMonsters() {
        ArrayList<Monster> monsters = new ArrayList<Monster>();
        monsters.add(new Monster(1, "牛魔王", "芭蕉扇", 500));
        monsters.add(new Monster(2, "蜘蛛精", "吐口水", 200));
        return monsters;
    }
}

6.修改SunWebApplicationContext.java的executeInstance方法,增加对Service注解的扫描
    //编写方法,将符合要求的类反射创建对象,并封装到单例池中
    public void executeInstance() {
        //遍历所有全类名
        for (String classPath : classFullPathList) {
            try {
                //反射
                Class<?> aClass = Class.forName(classPath);
                //判断是否有Controller注解
                if (aClass.isAnnotationPresent(Controller.class)) {
                    //有注解,当他是单例的,反射创建bean对象,放到单例池中,默认首字母小写
                    //获取类名首字母小写
                    String name = aClass.getSimpleName().substring(0, 1).toLowerCase() + aClass.getSimpleName().substring(1);
                    //放到单例池中
                    singleObjects.put(name, aClass.newInstance());
                } else if (aClass.isAnnotationPresent(Service.class)) {
                    //获取注解对象
                    Service annotation = aClass.getAnnotation(Service.class);
                    //获取注解的value
                    String value = annotation.value();
                    //为了使注入的都是同一个对象,所以在这里使用反射创建实例
                    Object bean = aClass.newInstance();
                    //如果注解的value是空的,则使用默认机制注入到单例池中
                    if ("".equals(value)) {
                        //1.使用类名首字母小写来注入
                        String simpleName = aClass.getSimpleName();
                        String beanName = simpleName.substring(0,1).toLowerCase() + simpleName.substring(1);
                        singleObjects.put(beanName, bean);
                        //2.使用接口名首字母小写来注入
                        Class<?>[] interfaces = aClass.getInterfaces();
                        //遍历所有接口类型,进行注入
                        for (Class<?> anInterface : interfaces) {
                            //获取接口的名称
                            String interfaceSimpleName = anInterface.getSimpleName();
                            //获取首字母小写
                            String beanName2 = interfaceSimpleName.substring(0,1).toLowerCase() + interfaceSimpleName.substring(1);
                            //进行注入
                            singleObjects.put(beanName2, bean);
                        }
                    } else {
                        //如果value不是空的,则按照value的值进行注入
                        singleObjects.put(value, bean);
                    }
                }
            } catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            } catch (InstantiationException e) {
                throw new RuntimeException(e);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        }
    }
7.debug测试

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc

3.完成自定义Autowired注解

1.自定义Autowired注解
package com.Sun.sunspringmvc.annotation;

import java.lang.annotation.*;

/**
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.FIELD) //作用目标是字段
@Retention(RetentionPolicy.RUNTIME) //作用范围
@Documented
public @interface AutoWired {
    String value() default "";
}

2.在SunWebApplicationContext.java中添加方法executeAutoWired完成属性的自动装配

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc

    //编写方法,完成属性的自动装配
    public void executeAutoWired() throws IllegalAccessException {
        //首先判断容器是否为空
        if (singleObjects.isEmpty()) {
            return;
        }
        //遍历容器中的所有bean对象
        for (Object beanObject : singleObjects.values()) {
            //得到Class对象
            Class<?> aClass = beanObject.getClass();
            //得到所有字段
            Field[] declaredFields = aClass.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                //判断这些字段是否有自动装配的注解
                if (declaredField.isAnnotationPresent(AutoWired.class)) {
                    //得到这个注解的value
                    AutoWired annotation = declaredField.getAnnotation(AutoWired.class);
                    String value = annotation.value();

                    Object findBeanObject = null; //用来存储从容器中查找到的值
                    //先判断这个注解的value有没有值
                    if ("".equals(value)) {
                        //如果注解没有值则按照默认的方式处理,即按照类型的首字母小写来查找
                        String simpleName = declaredField.getType().getSimpleName();
                        String beanName = simpleName.substring(0, 1).toLowerCase() + simpleName.substring(1);
                        //从容器中查找
                        findBeanObject = singleObjects.get(beanName);
                    } else {
                        //这个注解的value不是空的,则按照他的这个value在容器中查找
                        findBeanObject = singleObjects.get(value);
                    }

                    if (findBeanObject == null) {
                        throw new RuntimeException("容器中不存在你要装配的bean");
                    } else {
                        //进行依赖注入,需要指定给哪个对象的字段赋值
                        //反射爆破
                        declaredField.setAccessible(true);
                        declaredField.set(beanObject, findBeanObject);
                    }

                }
            }
        }
    }
3.修改MonsterController.java来使用Autowired注解

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc

4.单元测试

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc

实现SpringMVC底层机制(二),底层机制,java,开发语言,spring,springmvc文章来源地址https://www.toymoban.com/news/detail-859541.html

4.当前阶段完成的任务

自定义两个注解
  • 自定义Service注解:在原有的扫描所有文件全类名的基础上增加逻辑,判断是否具有Service注解,并根据value值或者默认方案将其注入到bean中
  • 自定义Autowired注解
    • 遍历所有单例池对象,获取对应的Class对象
    • 获取每个对象的所有字段
    • 对每个字段判断是否有Autowired注解,如果有则按照类型首字母小写或者value值来进行依赖注入
目前对SpringMVC容器的简单理解
  • tomcat启动,加载中央控制器
  • 获取spring配置文件路径,使用这个路径创建一个spring容器
  • 调用spring容器的init方法,初始化spring容器
    • 读取配置文件,得到要扫描的包,从而得到包的工作路径
    • 根据工作路径来得到包内所哟class文件的全路径
    • 遍历所有class文件的全路径,得到Class对象
    • 使用反射扫描指定注解,反射创建bean对象,放到单例池中
    • Autowired依赖注入
      • 扫描单例池,得到所有对象,从而得到Class对象
      • 使用反射得到所有字段信息,判断是否有Autowied注解,如果有则根据一定规则从单例池中查找bean对象进行依赖注入
  • 初始化映射对象列表
    • 扫描单例池,得到Class对象
    • 通过反射判断是否有RequestMapping注解,如果有则使用反射获取url和Method对象,再加上当前的对象,封装到映射对象中
    • 将这个映射对象添加到映射对象列表
  • 请求分发
    • 浏览器向中央控制器发送请求
    • 中央控制器根据请求的uri和映射对象列表的url进行比对
    • 如果匹配则反射调用Controller的方法

到了这里,关于实现SpringMVC底层机制(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java语言开发在线小说推荐网 小说推荐系统 基于用户、物品的协同过滤推荐算法 SSM(Spring+SpringMVC+Mybatis)开发框架 大数据、人工智能、机器学习开发

    1、开发工具和使用技术 MyEclipse10/Eclipse/IDEA,jdk1.8,mysql5.5/mysql8,navicat数据库管理工具,tomcat,SSM(spring+springmvc+mybatis)开发框架,jsp页面,javascript脚本,jquery脚本,bootstrap前端框架(用户端),layui前端框架(管理员端),layer弹窗组件等。 2、实现功能 前台用户包含:注

    2023年04月26日
    浏览(57)
  • Java开发之框架(spring、springmvc、springboot、mybatis)【面试篇 完结版】

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 本文主要记录spring的单例bean、切面编程AOP、spring事务、循环依赖、常见注解等 提示:以下是本篇文章正文内容,下面案例可供参考 ① 问题引入 Spring框架中的bean是单例的 singleton :bean在每个Spring IOC容

    2024年02月07日
    浏览(38)
  • (第十一天)初识SpringMVC SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录

    今天我们要来学习一下SSM框架的最后一个框架SpringMVC 一、初认SpringMVC 基本概念: ​ Spring MVC(Model-View-Controller)是一个用于构建Java Web应用程序的开源框架,它提供了一种基于MVC架构的方式来开发Web应用 。 ​ SpringMVC是Spring Framework的一部分,它是一种基于模型-视图-控制器(

    2024年02月07日
    浏览(55)
  • 【Spring+SpringMVC+Mybatis】Spring+SpringMVC+Mybatis实现前端到后台完整项目

    🌕博客x主页:己不由心王道长🌕! 🌎文章说明:Spring+SpringMVC🌎 ✅系列专栏:Spring 🌴本篇内容:使用Spring、SpringMVC对以前做过的项目进行重新整合和介绍。🌴 ☕️每日一语:宁愿因做自己而招人厌恶,也不愿为了迎合他人而伪装自己,懂你的人会留下来,不懂你的人,你

    2024年02月02日
    浏览(35)
  • Spring+SpringMVC+MyBatis整合项目开发(配有项目,已开源)

    🍰 个人主页:__Aurora__ 🍞 如果文章有什么需要改进的地方还请各位大佬斧正。 🍉如果我的文章对你有帮助➡️ 关注🙏🏻 点赞👍 收藏⭐️ 🔥最近在学SSM框架,本文是根据b站【黑马程序员 ssm框架 2021 版】整理。 🔥视频链接:https://www.bilibili.com/video/BV1WZ4y1P7Bp?spm_id_from=3

    2023年04月08日
    浏览(41)
  • SpringMVC底层原理源码解析

    SpringMVC的作用毋庸置疑,虽然我们现在都是用SpringBoot,但是SpringBoot中仍然是在使用SpringMVC来处理请求。 我们在使用SpringMVC时,传统的方式是通过定义web.xml,比如: 我们只要定义这样的一个web.xml,然后启动Tomcat,那么我们就能正常使用SpringMVC了。 SpringMVC中,最为核心的就是

    2024年02月05日
    浏览(35)
  • 【SpringMVC】9—底层原理

    ⭐⭐⭐⭐⭐⭐ Github主页👉https://github.com/A-BigTree 笔记链接👉https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以,麻烦各位看官顺手点个star~😊 如果文章对你有所帮助,可以点赞👍收藏⭐支持一下博主~😆 9.1.1 初始化操作调用路线 类和接口之间的关系 调用路线图 调用

    2023年04月10日
    浏览(23)
  • Java框架学习(二)SSM体系:Spring、SpringMVC、MybatisPlus

    在原始的分层架构实现中,负责响应请求的Controller层依赖于业务逻辑处理的Service层,而业务逻辑处理的service层又依赖与数据访问Dao层。上下层间相互依赖耦合,耦合的缺陷在于牵一发而动全身,不利于后期维护拓展。 为了分层解耦,Spring采用IoC控制反转和DI依赖注入,来解

    2024年02月11日
    浏览(35)
  • 基于ssm实现图书商城(spring+springmvc+mybatis)

    一、项目功能 前台 图书基本展示,包括推荐图书展示和类图书类型展示. 推荐图书包括条幅推荐,热销推荐和新品推荐. 按照图书类型展示商品. 图书详细信息展示. 图书加入购物车. 修改购物车内图书信息,例如数量等. 用户登录. 用户注册. 修改个人信息,包括密码和收获信息. 购

    2024年02月12日
    浏览(36)
  • Java项目:ssm框架基于spring+springmvc+mybatis框架的民宿预订管理系统设计与实现(ssm+B/S架构+源码+数据库+毕业论文)

    本项目是一套ssm827基于SSM框架的民宿预订管理系统设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的Java学习者。 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse 确保可以运行! 该系统功能

    2024年01月22日
    浏览(70)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包