自己实现 SpringMVC 底层机制 系列之-实现任务阶段 4- 完成自定义@Service 注解功能

2023-08-21 16:44:57

😀前言
自己实现 SpringMVC 底层机制 系列之-实现任务阶段 4- 完成自定义@Service 注解功能

🏠个人主页:尘觉主页
在这里插入图片描述

🧑个人简介:大家好,我是尘觉,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

在csdn获奖荣誉: 🏆csdn城市之星2名
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 💓Java全栈群星计划top前5
⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ ⁣⁣⁣⁣ 🤗 端午大礼包获得者

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

🥰实现任务阶段 4- 完成自定义@Service 注解功能

功能说明: 如果给某个类加上@Service, 则可以将其注入到我们的 Spring 容器

分析示意图

img

给 Service 类标注@Service, 可以将对象注入到 Spring 容器中

- 并可以通过接口名支持多级, 类名来获取到 Service Bean

结果为

monsterService=com.wyxdu.service.impl.MonsterServiceImpl@6cc86233, monsterServiceImpl=com.wyxdu.service.impl.MonsterServiceImpl@6cc86233,

创建代码

创建Monster类
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 +
                '}';
    }
}
创建自定义Service注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Service {
    String value() default "";
}
创建Service接口
public interface MonsterService{

    //增加方法-返回monster列表
    public List<Monster> listMonster();
}
创建MonsterServiceImpl实现类
@Service
public class MonsterServiceImpl implements MonsterService {
    @Override
    public List<Monster> listMonsters() {
        ArrayList<Monster> monsters = new ArrayList<>();
        monsters.add(new Monster(100, "牛魔王", "芭蕉扇", 500));
        monsters.add(new Monster(200, "蜘蛛精", "吐口水", 200));
        return monsters;
    }
}
修改wyxspringmvc.xml
<?xml version="1.0" encoding="utf-8" ?>
<beans>
    <!--指定要扫描的基本包以及子包的java类-->
    <component-scan base-package="com.wyxdu.controller,com.wyxdu.service"></component-scan>
</beans>
修改WyxWebApplicationContext
public void executeInstance() {
        //判断是否扫描到类
        if (classFullPathList.size() == 0) {//说明没有扫描到类
            return;
        }
        try {
            //遍历classFullPathList,进行反射
            for (String classFullPath : classFullPathList) {
                Class<?> clazz = Class.forName(classFullPath);
                //说明当前这个类有@Controller
                if (clazz.isAnnotationPresent(Controller.class)) {
                    //得到类名首字母小写
                    String beanName = clazz.getSimpleName().substring(0, 1).toLowerCase() +
                            clazz.getSimpleName().substring(1);
                    ioc.put(beanName, clazz.newInstance());
                } //如果有其它的注解,可以扩展 , 来处理@Service
                else if (clazz.isAnnotationPresent(Service.class)) {//如果类有@Serivce注解

                    //先获取到Service的value值=> 就是注入时的beanName
                    Service serviceAnnotation =
                            clazz.getAnnotation(Service.class);

                    String beanName = serviceAnnotation.value();
                    if ("".equals(beanName)) {//说明没有指定value, 我们就使用默认的机制注入Service
                        //可以通过接口名/类名[首字母小写]来注入ioc容器
                        //1.得到所有接口的名称=>反射
                        Class<?>[] interfaces = clazz.getInterfaces();

                        Object instance = clazz.newInstance();
                        //2. 遍历接口,然后通过多个接口名来注入
                        for (Class<?> anInterface : interfaces) {
                            //接口名->首字母小写
                            String beanName2 = anInterface.getSimpleName().substring(0, 1).toLowerCase() +
                                    anInterface.getSimpleName().substring(1);
                            ioc.put(beanName2, instance);
                        }

                        //3. 使用类名的首字母小写来注入bean
                        //   通过 clazz 来即可.
                        String beanName2 = clazz.getSimpleName().substring(0, 1).toLowerCase() +
                                clazz.getSimpleName().substring(1);
                        ioc.put(beanName2, instance);

                    } else {//如果有指定名称,就使用该名称注入即可
                        ioc.put(beanName, clazz.newInstance());
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
完成测试

(启动 Tomcat, 自动加载 wyxDispatcherServlet, 完成 IOC 容器的注入) 前面有结果

扫描后的ioc= {monsterService=com.wyxedu.service.impl.MonsterServiceImpl@6323a1c1,
orderController=com.wyxedu.controller.OrderController@4c96ec4f,
monsterController=com.wyxedu.controller.MonsterController@81664b3}

😄总结

本文完成了实现任务阶段 4- 完成自定义@Service 注解功能下一阶段
实现任务阶段 5- 完成 Spring 容器对象的自动装配 -@Autowried
                 
                 
😉自己实现 SpringMVC 底层机制 核心分发 控制器+ Controller 和 Service 注入容器 + 对象自动装配 + 控制器 方法获取参数 + 视图解析 + 返回 JSON 格式数系列

第一篇->自己实现 SpringMVC 底层机制 系列之搭建 SpringMVC 底层机制开发环境和开发 WyxDispatcherServlet_springmvc分发器

第二篇->自己实现 SpringMVC 底层机制 系列之–实现任务阶段 2- 完成客户端浏览器可以请求控制层

第三篇->自己实现 SpringMVC 底层机制 系列之–实现任务阶段 3- 从 web.xml动态获取 wyxspringmvc.xml

第四篇-> 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 4- 完成自定义@Service 注解功能

第五篇-> 自己实现 SpringMVC 底层机制 系列之-实现任务阶段 5- 完成 Spring 容器对象的自动装配 -@Autowried

第六篇->自己实现 SpringMVC 底层机制 系列之-实现任务阶段 6-完成控制器方法获取参数-@RequestParam

第七篇->自己实现 SpringMVC 底层机制 系列之-实现任务阶段 7- 完成简单视图解析

第八篇->自己实现 SpringMVC 底层机制 系列之-实现任务阶段 8- 完成返回 JSON 格式数据-@ResponseBody
                 
                 
                          
😁热门专栏推荐

想学习vue的可以看看这个

java基础合集

数据库合集

redis合集

nginx合集

linux合集

等等等还有许多优秀的合集在主页等着大家的光顾感谢大家的支持

🤔欢迎大家加入我的社区 尘觉社区

文章到这里就结束了,如果有什么疑问的地方请指出,诸佬们一起来评论区一起讨论😁
希望能和诸佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

更多推荐

[设计模式] 浅谈SOLID设计原则

目录单一职责原则开闭原则里氏替换原则接口隔离原则依赖倒转原则SOLID是一个缩写词,代表以下五种设计原则单一职责原则SingleResponsibilityPrinciple,SRP开闭原则Open-ClosedPrinciple,OCP里氏替换原则LiskovSubstitutionPrinciple,LSP接口隔离

华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法

目录专栏导读一、题目描述二、输入描述三、输出描述四、解题思路特别鸣谢:感谢fly晨发现这个问题,并提供更优质的算法。解题思路如下:五、Java算法源码六、效果展示1、输入2、输出3、思路专栏导读本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释

模式识别与人工智能(程序与算法)系列讲解 - 总目录

模式识别与人工智能(程序与算法)系列讲解-总目录作者:安静到无声作者简介:人工智能和硬件设计博士生、CSDN与阿里云开发者博客专家,多项比赛获奖者,发表SCI论文多篇。Thanks♪(・ω・)ノ如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!o( ̄▽ ̄)dლ(°◕‵ƹ′◕ლ)希望在传播知识、分享

【算法系列 | 8】深入解析查找算法之—二分查找

序言心若有阳光,你便会看见这个世界有那么多美好值得期待和向往。决定开一个算法专栏,希望能帮助大家很好的了解算法。主要深入解析每个算法,从概念到示例。我们一起努力,成为更好的自己!今天第8讲,讲一下查找算法的二分查找1基础介绍查找算法是很常见的一类问题,主要是将一组数据按照某种规则进行排序。以下是一些常见的查找算法及其应

通过 chatgpt 协助完成网站数据破解

Chatgpt的出现极大地提升了程序员的工作效率,常见的使用场景包括代码自动生成、代码静态检查等,那么chatgpt能否用于某些网站的数据破解工作呢?问题某天线上服务开始报警,原来是某个视频网站无法获取到其cdn地址导致的下载失败问题。经过debug发现原来的明文数据现在变成了加密数据(数据放在html中),如下由于职

Boostrap对HTML的表格的设计和优化

目录01-Bootstrap的默认表格风格02-没有边线-边界的表格03-行与行的背景颜色交替变换(条纹样式)04-给表格加上边框效果05-鼠标移到行上时该行的颜色加深06-把表格的padding值缩减一半,使表格看起来更紧凑07-为表格的行或单元格设置颜色01-Bootstrap的默认表格风格Bootstrap对表格

生信分析Python实战练习 9 | 视频27

开源生信Python教程生信专用简明Python文字和视频教程源码在:https://github.com/Tong-Chen/Bioinfo_course_python目录背景介绍编程开篇为什么学习Python如何安装Python如何运行Python命令和脚本使用什么编辑器写Python脚本Python程序事例Pyt

Springboot部署服务器项目上线

第一步,项目打包,有两种方式第一种、直接在项目根目录打开终端,输入以下语句即可。如下图:mvncleanpackage-DskipTests第二种、在右侧点击Maven选项,选择鼠标左键双击package选项即可。如下图:两种方法的结果,都会得到我们需要jar包,效果如下图:(可选项)如果觉得jar包名太难记,还可以在

“Vue进阶:深入理解插值、指令、过滤器、计算属性和监听器“

目录引言:Vue的插值Vue的指令Vue的过滤器Vue的计算属性和监听器vue购物车案例总结:引言:Vue.js是一款流行的JavaScript框架,它提供了许多强大的功能来简化前端开发。在本篇博客中,我们将深入探讨Vue的一些高级特性,包括插值、指令、过滤器、计算属性和监听器。通过理解和灵活运用这些功能,我们可以更好

10个值得关注的学习网站,知乎超30万人收藏,什么资源都可找到!

hi,大家好我是技术苟,每周准时上线为你带来实用黑科技!由于公众号改版,现在的公众号消息已经不再按照时间顺序排送了。因此小伙伴们就很容易错过精彩内容。喜欢黑科技的小伙伴,可以将黑科技百科公众号设为标星,这样就不会走丢啦~免责声明hello,朋友们,黑科技百科所有资源均为免费分享,绝多部分来源于互联网,所有资源仅提供学习

线程的方法(未完成)

线程的方法1.获取当前线程对象:CurrentThread()@Testpublicvoidbb(){Threadthread=Thread.currentThread();System.out.println(thread.getName());//打印main}2.currentThread().setName和c

热文推荐