自定义@Resource注解功能

news2024/9/21 0:45:24

文章目录

    • 1.目录
    • 2.Resource.java
    • 3.MonsterController.java 依赖注入Service调用方法
    • 4.SunWebApplicationContext.java
        • 1.executeResource方法完成依赖注入,先按照名字再按照类型
        • 2.init方法调用
    • 5.测试

1.目录

CleanShot 2024-08-07 at 16.42.13@2x

2.Resource.java

package com.sunxiansheng.springmvc.annotation;

import java.lang.annotation.*;

/**
 * Description: 自定义Resource注解,默认按照名字注入,如果没有名字,按照类型注入
 * @Author sun
 * @Create 2024/8/6 16:09
 * @Version 1.0
 */
@Retention(value = RetentionPolicy.RUNTIME) // 运行时生效
@Target(value = ElementType.FIELD) // 作用在类上
@Documented // 生成文档
public @interface Resource {

    String name() default "";

}

3.MonsterController.java 依赖注入Service调用方法

package com.sunxiansheng.controller;

import com.sunxiansheng.entity.Monster;
import com.sunxiansheng.service.MonsterService;
import com.sunxiansheng.springmvc.annotation.Controller;
import com.sunxiansheng.springmvc.annotation.RequestMapping;
import com.sunxiansheng.springmvc.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

/**
 * Description: 怪物控制器
 * @Author sun
 * @Create 2024/8/6 16:04
 * @Version 1.0
 */
@Controller
public class MonsterController {

    @Resource
    private MonsterService monsterService;

    // 日志
    private static final Logger log = LoggerFactory.getLogger(MonsterController.class);

    /**
     * 查询怪物列表
     * @param request
     * @param response
     */
    @RequestMapping(url = "/list/monster")
    public void listMonster(HttpServletRequest request, HttpServletResponse response) {
        // 设置响应类型
        response.setContentType("text/html;charset=utf-8");
        try {
            // 输出怪物列表
            PrintWriter writer = response.getWriter();
            List<Monster> monsters = monsterService.listMonster();
            // 响应id、name、skill、age
            for (Monster monster : monsters) {
                writer.println("id: " + monster.getId() + ", name: " + monster.getName() + ", skill: " + monster.getSkill() + ", age: " + monster.getAge());
            }
            // 日志
            log.info("查询怪物列表成功");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

4.SunWebApplicationContext.java

1.executeResource方法完成依赖注入,先按照名字再按照类型
    /**
     * 完成依赖注入
     */
    private void executeResource() {
        if (ioc.isEmpty()) {
            return;
        }
        // 遍历所有的类
        ioc.forEach((key, value) -> {
            try {
                // 获取类对象
                Class<?> clazz = value.getClass();
                // 获取所有的属性
                Field[] fields = clazz.getDeclaredFields();
                for (Field field : fields) {
                    // 判断是否有特定注解
                    if (field.isAnnotationPresent(Resource.class)) {
                        // 获取注解
                        Resource resource = field.getAnnotation(Resource.class);
                        // 获取注解的name属性
                        String name = resource.name();
                            // 按照名字注入
                            // 从IOC容器中获取这个对象
                            Object o = ioc.get(name);
                            // 如果为空,就按照类型注入
                            if (Objects.isNull(o)) {
                                // 获取属性的类型
                                Class<?> type = field.getType();
                                // 获取属性的类名,并且首字母小写
                                String keyName = toLowerFirstWord(type.getSimpleName());
                                // 从IOC容器中获取这个对象
                                o = ioc.get(keyName);
                            }
                            // 设置属性的值
                            field.setAccessible(true);
                            field.set(value, o);
                            if (Objects.nonNull(o)) {
                                log.info("依赖注入成功,属性名:{},属性值:{}", field.getName(), o);
                            }
                        }
                    }

            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }
2.init方法调用

CleanShot 2024-08-07 at 16.45.22@2x

5.测试

CleanShot 2024-08-07 at 16.45.58@2x

CleanShot 2024-08-07 at 16.46.07@2x

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2075478.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux网络配置和系统管理

Linux网络配置和系统管理 1.查看网络IP和网关windows系统主机 IP虚拟机 IP虚拟机网关网络检测命令 ping网络连接模式 2.配置静态IP地址(NAT网络连接模式)前提说明配置主机的VMware Network Adapter VMnet8 网卡静态IP地址注意点虚拟机配置静态ip修改后ping命令测试修改虚拟机静…

选择泛域名证书还是多域名证书?

在选择泛域名SSL证书&#xff08;也称为通配符SSL证书&#xff09;和多域名证书时&#xff0c;需要综合考虑多个因素&#xff0c;包括业务需求、成本效益、灵活性以及未来规划等。以下是对这两种证书的比较及选择建议&#xff1a; 一、定义与特点 泛域名SSL证书&#xff08;通…

智能巡检系统,确保到位管理,提升安全效率新境界

在现代工业生产与设施管理中&#xff0c;巡检作为确保设备安全、预防故障发生的重要环节&#xff0c;其效率与准确性直接关系到企业的运营安全与经济效益。然而&#xff0c;传统的人工巡检方式往往存在巡检周期长、覆盖面有限、数据记录易出错、隐患难以及时发现等痛点&#xf…

大模型分布式训练进阶之路:数据并行、管道并行、张量并行、3D并行

系统化的学习大模型&#xff0c;除了知道大模型是什么&#xff0c;也得知道大模型是如何训练的&#xff0c;对大模型的实际应用有更加定量的认知&#xff0c;该文章也算是一篇分布式训练的学习过程总结&#xff0c;作为循序渐进学习分布式训练的总结。 类似之前写过的LLM文章&…

U盘怎么加密保护?U盘加密软件哪个好?

在工作和生活中&#xff0c;我们经常需要使用U盘来存储数据。而为了避免U盘数据泄露&#xff0c;我们需要加密保护U盘。那么&#xff0c;U盘加密软件哪个好呢&#xff1f;下面我们就一起来了解一下。 BitLocker加密 BitLocker是Windows系统提供的磁盘加密功能&#xff0c;可以…

DevOps实现CI/CD实战(三)- 集成Sonar Qube

七、集成Sonar Qube 1. SonarQube介绍 Sonar Qube是一个开源的代码分析平台&#xff0c;支持Java、Python、PHP、JavaScript、CSS等25种以上的语言&#xff0c;可以检测出重复代码、代码漏洞、代码规范和安全性漏洞的问题。 Sonar Qube可以与多种软件整合进行代码扫描&#…

大龄程序员转行AI大模型:机遇与挑战解析

前言 对于大龄程序员而言&#xff0c;转行到AI大模型领域是一个既充满挑战又极具吸引力的选择。在这个领域&#xff0c;您将有机会接触到最新的技术趋势&#xff0c;参与到前沿的项目中&#xff0c;并且有可能获得更高的薪酬。下面是一些具体的步骤和建议&#xff0c;帮助您顺…

普通人用 AI 变现的4大方向

前言 AI出现&#xff0c;几家欢喜几家愁。 有人担心受怕恐因AI被裁&#xff0c;有人却早已利用AI躺赚&#x1f4b0;。 “利用AI发展副业的方式究竟有哪些&#xff1f;怎么样才能利用AI做到躺赚&#xff1f;” 我相信这是绝大部分人的疑惑点&#xff0c;包括我&#xff01;&…

【AI大模型】提示词(Prompt)全面解析

文章目录 前言前置准备&#xff08;非常重要&#xff09;一、Prompt 提示词介绍1.1 Prompt 的重要性 二、Prompt 提示词元素构成与实践2.1 关键字2.2 上下文2.3 格式要求2.4 实践示例 三、Prompt 提示词编写原理3.1 清晰性3.2 具体性3.3 适应性 四、Prompt 提示词编写常用的分隔…

LLaMA Factory微调Llama3模型

LLaMA Factory是一款开源低代码大模型微调框架&#xff0c;集成了业界最广泛使用的微调技术&#xff0c;支持通过Web UI界面零代码微调大模型&#xff0c;目前已经成为开源社区内最受欢迎的微调框架。 &#x1f4a5;GPU推荐使用24GB显存的A10&#xff08;ecs.gn7i-c8g1.2xlarg…

Stable Diffusion【XL Lora】效果太赞了!AI助力服装设计,让服装拆分设计就是这么高效

今天带了一款 非常适合服装设计的SD XL Lora模型——【服装拆分】绪儿 分类背景 XUER&#xff0c;该模型是由绪儿大佬炼制&#xff0c;非常适合饰品服装分类背景。绪儿大佬其实推出了很多非常棒的模型&#xff0c;比如之前非常受大家喜欢的敦煌飞天、超梦幻场景等模型。 那么我…

如何区分住宅代理与数据中心代理?

随着代理市场的蓬勃发展&#xff0c;不同类型的代理服务应运而生&#xff0c;其中住宅代理与数据中心代理尤为常见。如何区分住宅代理与数据中心代理&#xff0c;成为了诸多用户面临的难题&#xff0c;本文将与大家详细探讨如何区分这二种代理。 首先&#xff0c;我们来看住宅代…

【解压即玩】使命召唤 系列-2,回味经典

《使命召唤2》&#xff08;英语&#xff1a;Call of Duty 2&#xff0c;香港和台湾译作“决胜时刻2”&#xff09;于2005年推出&#xff0c;游戏提供了苏军、英军、美军三大阵营的战役&#xff0c;重现了二战中的经典战役&#xff0c;例如莫斯科保卫战、斯大林格勒保卫战、诺曼…

VTK随笔五:VTK数据的读写

VTK应用程序所需的数据可以通过两种途径获取&#xff1a;第一种是生成模型&#xff0c;然后处理这些模型数据(如由类 vtkCylinderSource 生成的多边形数据)&#xff1b;第二种是从外部存储介质里导入相关的数据文件&#xff0c;然后在应用程序中处理这些读入的数据(如vkBMPRead…

三网话费充值api接口有哪些优势?你了解多少?

一、话费充值 API 接口定义 话费充值 API 接口是一种专门为实现话费充值业务而设计的接口。通过接入该接口&#xff0c;个人或企业可以搭建话费充值平台&#xff0c;其界面展示与官方平台充值页面相似&#xff0c;可自动配置充值范围并支持三大运营商话费充值。 二、话费接口…

专业版SSL证书:强化网站安全的首选

专业版SSL证书&#xff0c;专为追求极致网站安全的企业设计。它不仅提供高强度的加密保护&#xff0c;有效防止数据在传输过程中被窃取或篡改&#xff0c;还通过严格的身份验证流程&#xff0c;向访客展示网站的真实身份。其独特的绿色地址栏或公司名显示功能&#xff0c;显著增…

打手机检测算法源码样本展示打手机检测算法实际应用场景介绍

打手机检测算法是一种利用计算机视觉技术来监测和识别人们在特定区域如驾驶舱、考场或其他敏感区域非法使用手机的行为。这种算法对于提高安全性和确保规则的遵守具有重要意义。以下是关于打手机检测算法源码及其实际应用的详细阐述&#xff1a; 1. 算法实现 - 深度学习框架&a…

探秘小米SU7亏损背后的真相:雷军的战略布局与汽车行业的逆袭

近日&#xff0c;小米发布了史上最佳单季财报&#xff0c;营收达到了889亿元&#xff0c;同比增长20.1%。然而&#xff0c;小米汽车业务的亏损依然引发了广泛关注。特别是&#xff0c;小米SU7每卖一辆亏损约6万元&#xff0c;但雷军对此却显得非常淡定甚至乐观。这背后究竟隐藏…

Leetcode面试经典150题-72.编辑距离

解法都在代码里&#xff0c;不懂就留言或者私信 动态规划最经典题之一&#xff0c;如果写不出来&#xff0c;动态规划好好再学学 class Solution {/**这个题是动态规划最经典的题&#xff0c;另一个最经典的是背包问题 */public int minDistance(String word1, String word2)…

解读vue3源码-响应式篇3 effect副作用函数

提示&#xff1a;看到我 请让我滚去学习 文章目录 前言effect问题拓展分支切换与 cleanup嵌套的 effect 与 effect 栈解决在副作用函数中同时读取和操作同一属性时无限循环 effect函数实现computed-api 实现图解在这里插入图片描述 总结 前言 什么是副作用函数&#xff1f; 在…