基于注解配置bean

文章目录

    • 1.基本使用
        • 1.基本介绍
        • 2.快速入门
          • 1.引入jar包
          • 2.MyComponent.java
          • 3.UserAction.java
          • 3.UserDao.java
          • 4.UserService.java
          • 5.beans05.xml
          • 6.断点查看bean对象是否创建
          • 7.测试
        • 3.注意事项和细节
    • 2.自己实现spring注解
        • 1.需求分析
        • 2.思路分析图
        • 3.编写自定义注解ComponentScan
        • 4.编写配置类SunSpringConfig
        • 5.编写容器SunSpringApplicationContext
        • 6.测试
    • 3.自动装配
        • 1.AutoWired方式
          • 1.基本说明
          • 2.UserDao.java
          • 3.UserService.java
          • 4.测试
        • 2.Resource方式(推荐)
          • 1.基本说明
          • 2.UserDao.java
          • 3.UserService.java
    • 4.泛型依赖注入
        • 1.基本说明
          • 1.基本介绍
          • 2.参考关系图

1.基本使用

1.基本介绍

image-20240219101916177

2.快速入门
1.引入jar包

image-20240219102154951

2.MyComponent.java
package com.sxs.spring.component;

import org.springframework.stereotype.Component;

/**
 * @Component 标识该类是一个组件,当不确定该类的层级的时候就使用这个注解
 * @author 孙显圣
 * @version 1.0
 */

@Component
public class MyComponent {
}

3.UserAction.java
package com.sxs.spring.component;

import org.springframework.stereotype.Controller;

/**
 * @Controller 用于标识该类是一个控制器(相当于servlet)
 * @author 孙显圣
 * @version 1.0
 */
@Controller
public class UserAction {
}

3.UserDao.java
package com.sxs.spring.component;

import org.springframework.stereotype.Repository;

/**
 * @Repository 用来标识该类是一个dao
 * @author 孙显圣
 * @version 1.0
 */
@Repository
public class UserDao {
}

4.UserService.java
package com.sxs.spring.component;

import org.springframework.stereotype.Service;

/**
 * @Service 用于标识该类是一个Service
 * @author 孙显圣
 * @version 1.0
 */
@Service
public class UserService {
}

5.beans05.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!--
        component-scan 表示对指定包下的类进行扫描,并创建对象到容器
        base-package 指定要扫描的包
    -->
    <context:component-scan base-package="com.sxs.spring.component"></context:component-scan>
</beans>
6.断点查看bean对象是否创建

image-20240219104840942

7.测试
    //通过注解来配置bean
    @Test
    public void setBeanByAnnotation() {
        //从类路径下读取配置文件
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
        //分别获取这四个对象,由于是单例的所以可以直接通过类型获取
        MyComponent component = ioc.getBean(MyComponent.class);
        UserAction action = ioc.getBean(UserAction.class);
        UserDao userDao = ioc.getBean(UserDao.class);
        UserService userService = ioc.getBean(UserService.class);
        System.out.println("" + component + action + userDao + userService);
    }

image-20240219105551384

3.注意事项和细节

image-20240219105946438

image-20240219133850259

image-20240219133918902

image-20240219134100805

image-20240219134942963

2.自己实现spring注解

1.需求分析

image-20240219135303466

image-20240219135325093

2.思路分析图

image-20240219140946226

3.编写自定义注解ComponentScan
package com.sxs.spring.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 自定义注解:用于指定要扫描的包
 *
 * @author 孙显圣
 * @version 1.0
 */
@Target(ElementType.TYPE) //指定目前的注解可以修饰TYPE程序元素
@Retention(RetentionPolicy.RUNTIME) //指定注解的保留范围,在运行时可以生效
public @interface ComponentScan {
    String value() default ""; //指定注解可以传入一个String类型的值,用于指定要扫描的包
}

4.编写配置类SunSpringConfig
package com.sxs.spring.annotation;

/**
 * @author 孙显圣
 * @version 1.0
 */
@ComponentScan(value = "com.sxs.spring.component") //自定义注解:指定要扫描的包
public class SunSpringConfig {

}

5.编写容器SunSpringApplicationContext
package com.sxs.spring.annotation;

import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.File;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 类似于Spring原生的ioc容器
 *
 * @author 孙显圣
 * @version 1.0
 */
public class SunSpringApplicationContext {
    //传进来一个配置类的Class对象
    private Class configClass;
    //存放对象的容器
    private final ConcurrentHashMap<String, Object> ioc = new ConcurrentHashMap<>();
    //构造器,接收配置类的class对象
    public SunSpringApplicationContext(Class configClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        this.configClass = configClass;
        //获取要扫描的包
        //1.首先反射获取类的注解信息
        ComponentScan componentScan = (ComponentScan) this.configClass.getDeclaredAnnotation(ComponentScan.class);
        //2.通过注解来获取要扫描的包的路径
        String path = componentScan.value();

        //得到要扫描包的.class文件
        //1.获取类加载器
        ClassLoader classLoader = SunSpringApplicationContext.class.getClassLoader();
        //2.获取要扫描包的真实路径,默认刚开始在根目录下
        path = path.replace(".", "/");
        URL resource = classLoader.getResource(path);
        //3.由该路径创建一个文件对象,可使用resource.getFile()将URL类型转化为String类型
        File file = new File(resource.getFile());
        //4.遍历该文件夹下的所有.class文件
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (File f : files ) {
                //反射注入容器
                //1.获取所有文件的全路径
                String absolutePath = f.getAbsolutePath();
                //只处理class文件
                if (absolutePath.endsWith(".class")) {
                    //2.分割出类名
                    String className = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.indexOf("."));
                    //3.得到全路径
                    String fullPath = path.replace("/", ".") + "." + className;
                    //4.类加载器获取Class对象(也可以通过Class.forName,区别是后者会使类被静态初始化),判断是否有那四个注解
                    Class<?> aClass = classLoader.loadClass(fullPath);
                    if (aClass.isAnnotationPresent(Component.class) || aClass.isAnnotationPresent(Controller.class)
                    || aClass.isAnnotationPresent(Service.class) || aClass.isAnnotationPresent(Repository.class)) {
                        //5.反射对象并放入到容器中
                        Class<?> clazz = Class.forName(fullPath);
                        Object o = clazz.newInstance();
                        //默认是类名首字母小写作为key
                        ioc.put(StringUtils.uncapitalize(className), o);
                    }
                }
            }
            System.out.println("ok");
        }
    }

    //返回容器中的对象
    public Object getBean(String name) {
        return ioc.get(name);
    }

}

6.测试
package com.sxs.spring.annotation;

import org.junit.jupiter.api.Test;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class test {
    @Test
    public void SunSpringApplicationContextTest() throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        SunSpringApplicationContext ioc = new SunSpringApplicationContext(SunSpringConfig.class);
        Object myComponent = ioc.getBean("myComponent");
        Object userAction = ioc.getBean("userAction");
        Object userDao = ioc.getBean("userDao");
        Object userService = ioc.getBean("userService");
        System.out.println("" + myComponent + userService + userAction + userDao);
    }
}

image-20240219160545576

3.自动装配

1.AutoWired方式
1.基本说明

image-20240219172851649

2.UserDao.java
package com.sxs.spring.component;

import org.springframework.stereotype.Repository;

/**
 * @Repository 用来标识该类是一个dao
 * @author 孙显圣
 * @version 1.0
 */
@Repository
public class UserDao {
    public void sayHi() {
        System.out.println("hi");
    }
}

3.UserService.java
package com.sxs.spring.component;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @Service 用于标识该类是一个Service
 * @author 孙显圣
 * @version 1.0
 */
@Service
public class UserService {
    //自动装配
    //1.通过UserDao这个类型来匹配,如果有多个实例,则使用第二种方式匹配
    //2.通过userDao这个属性名字作为id匹配实例,如果还是匹配不到则报错
    @Autowired
    UserDao userDao;

    public void sayHi() {
        userDao.sayHi();
    }
}

4.测试
    //测试@autowire自动装配
    @Test
    public void autowireTest() {
        //获取容器
        ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");
        UserService bean = ioc.getBean("userService", UserService.class);
        bean.sayHi();
    }

image-20240219173043506

2.Resource方式(推荐)
1.基本说明

image-20240219173244707

2.UserDao.java
package com.sxs.spring.component;

import org.springframework.stereotype.Repository;

/**
 * @Repository 用来标识该类是一个dao
 * @author 孙显圣
 * @version 1.0
 */
@Repository
public class UserDao {
    public void sayHi() {
        System.out.println("hi");
    }
}

3.UserService.java
package com.sxs.spring.component;

import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @Service 用于标识该类是一个Service
 * @author 孙显圣
 * @version 1.0
 */
@Service
public class UserService {
    //自动装配
    //1.通过name匹配:直接根据注解的属性name来进行匹配,如果匹配不到直接报错
    //2.通过类型匹配:必须保证是单例的,如果有多个实例,则直接报错
    //3.默认:先通过name属性匹配,如果匹配不上则按照类型匹配,都匹配不上才会报错
    @Resource
    UserDao userDao;

    public void sayHi() {
        userDao.sayHi();
    }
}

4.泛型依赖注入

1.基本说明
1.基本介绍

image-20240219184142629

2.参考关系图

image-20240219185501222

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

今日arXiv最热NLP大模型论文:面向不确定性感知的Language Agent

引言&#xff1a;面向不确定性的感知的Language Agent Language Agent利用大型语言模型&#xff08;如OpenAI发布的GPT系列、Meta的LLaMA2等&#xff09;来与外部世界互动&#xff0c;例如通过工具和API收集观察结果&#xff0c;并处理这些信息以解决任务。这些Language Agent…

javaWeb项目-智能仓储系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、JSP技术 JSP(Jav…

UE5集成gRPC

最近有项目需要在UE5里做RPC&#xff0c;对比了thrift、gRPC、rcplib等开源rpc框架&#xff0c;由于习惯使用protobuf&#xff0c;故选择了gRPC。然而&#xff0c;Google出品也是一言难尽啊&#xff0c;最起码编译太繁琐了。 本次使用的gRPC版本为1.62.1&#xff0c;UE5.2&…

二分答案复习

y总二分查找算法模板 int bsearch_1(int l, int r) {while (l < r){int mid l r >> 1;//性质在右边&#xff0c;区间划分成[l, mid]和[mid 1, r]if (check(mid)) r mid;else l mid 1;}return l; }int bsearch_2(int l, int r) {while (l < r){int mid l r …

科普馆VR技术展现安全场景,构建安全教育新标杆!

随着VR技术的快速发展&#xff0c;其所衍生出的互动装置&#xff0c;悄无声息地渗透进了我们生活的每个角落&#xff0c;就连那严谨而重要的安全教育领域&#xff0c;也没能逃出这神奇魔法的“魔爪”&#xff0c;这种VR互动设备简直就是安全知识传递的小能手&#xff0c;那么&a…

SpringCloud系列(7)--Eureka服务端的安装与配置

前言&#xff1a;上一章节我们介绍了Eureka的基础&#xff0c;本章节则介绍Eureka服务端的安装与配置 Eureka架构原理图 1、创建Eureka Server端服务注册中心模块 (1)在父工程下新建模块 (2)选择模块的项目类型为Maven并选择模块要使用的JDK版本 (3)填写子模块的名称&#xf…

llama-factory SFT 系列教程 (四),lora sft 微调后,使用vllm加速推理

文章目录 文章列表&#xff1a;背景简介llama-factory vllm API 部署融合 lora 模型权重 vllm API 部署HuggingFace API 部署推理API 部署总结 vllm 不使用 API 部署&#xff0c;直接推理数据集 tenplatevllm 代码部署 文章列表&#xff1a; llama-factory SFT系列教程 (一)&a…

SpringMVC(三)【REST 风格】

1、REST 风格 1.1、REST 简介 REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表现形式状态转换 在开发中&#xff0c;它其实指的就是访问网络资源的格式 1.1.1、传统风格资源描述形式 http://localhost/user/getById?id1http://localhost/user…

18 统计网站每日的访问次数

1.将竞赛的数据上传HDFS,查看数据的格式 通过浏览器访问hdfs,查看该文档前面的部分数据 每条数据的字段值之间使用逗号隔开的 &#xff0c;最终时间是第五个自动&#xff0c;获取第五个字段值的中的年月日。 2.通过Idea创建项目mr-raceData ,基础的配置 修改pom.xml,添加依赖 …

一文读懂uniapp中的tabBar底部导航

目录 1. 基本知识2. Demo 1. 基本知识 UniApp 中的 tabBar 是用来在应用程序底部显示可切换的选项卡的组件&#xff0c;通常用于实现底部导航栏 允许用户通过点击不同的选项卡来切换应用程序的不同页面或功能模块 其代码如下&#xff1a; "tabBar":{"color&q…

HoloLens2的Unity应用在电脑上发布成安装包,然后通过wifi安装到设备

一、VS工程中的鼠标右键 二、发布——>创建应用程序包 三、选择【旁加载】 四、选择签名方法&#xff1a; 五、选择和配置包 六、创建完毕 七、网络连接设备 八、登录设备 九、安装app

spring高级篇(二)

1、Aware和InitializingBean Aware和InitializingBean都与Bean的生命周期管理相关。 Aware接口: 概念: Aware接口是Spring框架中的一个标记接口&#xff0c;它表示一个类能够感知到&#xff08;aware of&#xff09;Spring容器的存在及其特定的环境。Spring框架提供了多个Awar…

Android自带模拟器如何获得ROOT权限

如果在模拟器中不能切换到root权限&#xff0c;很可能是镜像使用的不对。 一.选择镜像标准&#xff1a; 1.运行在PC端选X86_64镜像&#xff0c;才能流畅运行 2.不带google api的镜像 二.步骤 在虚拟机管理器中新建AVD&#xff0c;并下载符合要求的镜像文件 三.验证

shell脚本编程的例子(55例子)-3

第三部分&#xff1a;eg32-eg50shell例子。开放一周后启用vip阅读了。…… ^v^ Eg32、while/until/for经典例子 #!/bin/bash ## filename: while-infinite_loops.sh while true; do sleep 5 echo "infinite loops [ hit CTRLC to stop]" done Eg33、while/…

Rokid AR Lite空间计算套装发布,软硬件全面升级推动居家、出行、户外场景大规模应用

4月20日&#xff0c;以“好玩、好看、好上头”为主题的Rokid Open Day 2024发布会在杭州举行&#xff0c;Rokid对外正式发布新一代AR Lite空间计算套装&#xff0c;分享了近期Rokid在AR开发者生态和数字文化领域的进展和成果&#xff0c;并宣布了多项跨行业重磅合作。作为中国代…

PS-ZB转座子分析流程2-重新分析并总结

数据处理 数据质控 随机挑出九个序列进行比对&#xff0c;结果如下&#xff1a; 所有序列前面的部分序列均完全相同&#xff0c;怀疑是插入的转座子序列&#xff0c;再随机挑选9个序列进行比对&#xff0c;结果如下&#xff1a; 结果相同&#xff0c;使用cutadapt将该段序列修…

OerOerlikonTCO1200欧瑞康LPCVD system操作使用说明

OerOerlikonTCO1200欧瑞康LPCVD system操作使用说明

常见的经典目标检测算法

目标检测是计算机视觉领域的一个核心任务&#xff0c;它涉及到识别图像中的物体并确定它们的位置。以下是一些常见的经典目标检测算法&#xff1a; R-CNN系列 R-CNN&#xff08;Region-based Convolutional Neural Network&#xff09;是一种用于目标检测的算法&#xff0c;它…

PyQt5开发的DSP信号仿真系统

PyQt5开发的DSP信号仿真系统 1、效果图 2、功能 具备的功能: 1、生成基础信号波形[正弦波,脉冲函数,阶跃函数,斜坡函数, 锯齿波,方波,常见非周期波形,sinc函数] 2、各基础波形可以叠加 3、可展示FFT频谱、信号卷积、功率频谱密度估计 4、可以读取音频信号及分析 5、各…

第23天:安全开发-PHP应用后台模块SessionCookieToken身份验证唯一性

第二十三天 一、PHP后台身份验证模块实现 二、Cookie&Session技术&差异 1.生成cookie的原理图过程&#xff1a;见上图 客户端向服务器发送HTTP请求。服务器检查请求头中是否包含cookie信息。如果请求头中包含cookie信息&#xff0c;则服务器使用该cookie来识别客户端…