spring 学习 (注解)

news2025/2/15 11:28:11

目录

前言

常用的注解

须知

1 @Conponent注解

demo(案例)

2 @Controller+@Service+@Repository

demo(案例)

3 @Scope+@Lazy+@PostConstruct+@PreDestroy

demo(案例)

4 @Value+@Autowired+@Qualifier+@Resource

demo(案例)

5 @Configuration+@ComponentScan+@PropertySource+@import

demo(实例)


前言

之前学习 spring 框架时,我们知道实例化bean 都是依靠 spring 配置文件,在配置文件中书写一个个bean 标签,表示将要创建的对象。

本篇博客则是 使用注解的方式,平替之前使用 spring 配置文件创建对象,等操作。

Spring的注解可以代替xml配置;通俗点来讲,注解是对xml配置的平替;原先xml配置所实现的功能,现在可以使用注解实现;而且使用注解比xml配置更符合我们编码习惯,也更简单。

常用的注解

须知

以下任何demo(案例的前提)

即使我们使用各自注解代替 标签,属性啥的。但如何去解析 注解这是我们需要思考的。

以下在配置文件中写的 标签就是解析哪个包下的注解。

<?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
       http://www.springframework.org/schema/context/spring-context.xsd">

  <!--spring会去扫描fs包及其子包下所有的注解,并让其生效-->
<context:component-scan base-package="fs">
</context:component-scan>
</beans>

注意:

1 base-package 的属性值 是 你需要扫描哪个包下的注解

2 不要直接复制粘贴,看需要哪个补充哪个,否则很容易出问题。

3 当然了,这些最后同样会有相应注解替代 配置文件,扫描注解的标签。但需要注意任何注解的底层都是 以xml 配置文件的形式存在。


1 @Conponent注解

使用目的

@Conponent注解 就可以平替<bean>标签。

特别提醒:在使用spring注解的时候,要想使spring容器认识这些注解,我们需要在bean.xml文件中配置注解组件扫描,只有配置了组件扫描,spring才会去指定包下面扫描你使用了哪些注解,并让其生效。

	<!--spring会去扫描com.frank包及其子包下所有的注解,并让其生效-->
    <context:component-scan base-package="com.frank"></context:component-scan>

demo(案例)

使用 Conponent 注解 创建 person 类

person 类,Test 测试类

package fs.exerise;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
 @Component("person")
public class Person {
}
class Test{
    public static void main(String[] args) {
     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
     Object bean = context.getBean("person");
     System.out.println(bean);
    }
}

效果展示

注意:component 注解里的值,可以理解为表示 之前在spring 配置文件 bean 标签的id 值。


2 @Controller+@Service+@Repository

我们在实际的开发过程中是按层来进行的;为了语义上面更加明确,所以衍生出来另外三个注解来代替@Conponent。他们的作用是为了在语义上更加明确。

@Controller注解:使用在Controller层的类上面

@Service注解:使用在Service层的类上面

@Repository注解:使用在Dao层的类上面


demo(案例)


3 @Scope+@Lazy+@PostConstruct+@PreDestroy

@Scope注解:平替<bean scope="">

@Lazy注解:平替<bean lazy-init="">

@PostConstruct注解:平替<bean init-method="">

@PreDestroy注解:平替<bean destroy-method="">


demo(案例)

UserController 类

package fs.controller;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
// 相当于本类 UserController 在 配置文件的 bean 标签
@Controller("user")
// scope 属性表示作用域
@Scope(value = "singleton")
public class UserController {

    public UserController() {
        System.out.println("创建UserController");
    }
    // @PostConstruct 注解表示初始化方法
@PostConstruct
    public void init () {
        System.out.println("UserController初始化");
    }
    // @PreDestroy 注解表示销毁方法
@PreDestroy
    public void destroy () {
        System.out.println("UserController销毁");
    }
}

Test 测试类

package fs.controller;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class test {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("spring.xml");
       UserController userController = (UserController) app.getBean("user");
// 关闭 spring 容器 
         
app.close();
    }

}

效果展示


4 @Value+@Autowired+@Qualifier+@Resource

平替bean标签注入时的标签

原先使用xml实现注入的时候使用的是<property>标签来指明注入的关系;现在我们可以通过下面的注解来替换它。

@value注解:使用在字段或者方法上面,用于注入普通数据

@Autowired注解:使用在字段或者方法上面,用于注入引用数据(默认按照byType方式进行注入)

@Qualifier注解:使用在字段或者方法上面,搭配@Autowired根据名称进行注入

@Resource注解:使用在字段或者方法上面,根据类型或者名称进行注入


demo(案例)

userController 类

package fs.controller;

import fs.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
// 相当于本类 UserController 在 配置文件的 bean 标签
@Controller("user")
// scope 属性表示作用域
@Scope(value = "singleton")
public class UserController {
    @Autowired
    // @Autowired 注解表示自动注入 一般适用于 成员变量
// @Qualifier 可以为 @Autowired 注解的补充,表示注入的bean的id
    @Qualifier("userService")
    private UserService userService;
    // @Value 注解表示注入值
    @Value("dj")
    private  String name;
    public void a(){
        System.out.println(userService+"他的名字是"+name);
    }
    public UserController() {
        System.out.println("创建UserController");
    }
    // @PostConstruct 注解表示初始化方法
@PostConstruct
    public void init () {
        System.out.println("UserController初始化");
    }
    // @PreDestroy 注解表示销毁方法
@PreDestroy
    public void destroy () {
        System.out.println("UserController销毁");
    }
}

疑问:@Autowired注解是根据类型进行注入的,那如果我有多个UserDao类型呢?

答:所以这个时候@Qualifier注解的作用就起来了,它的作用是当发现你使用了@Autowired注解后,却有多个相同的类型,可以通过@Qualifier注解指定其中的一个名字进行注入(按名字注入)。

看案例:

我再新建一个UserDaoImp2类,让该类也去实现UserDao接口,重新观察 UserController 类

UserDaoImp1 类
package fs.Dao.impl;

import fs.Dao.UserDao;
import org.springframework.stereotype.Repository;

@Repository("UserDao1")
public class UserDaoImp1 implements UserDao {
}
UserDaoImpl2 类
package fs.Dao.impl;

import fs.Dao.UserDao;
import org.springframework.stereotype.Repository;

@Repository("UserDao2")
public class UserDaoImpl2 implements UserDao {
}

UserController 类

发现 ,因为存在 多个 userDao 的实现类,即使使用 Autowired 注解 也不知道 选择哪一个。

因此采取办法是 使用@Qualifier注解 选择其中一个 注入 进去

注意:@Resource注解:不给参数的时候相当于@Autowired进行注入;给了参数相当于@Autowired+@Qualifier


5 @Configuration+@ComponentScan+@PropertySource+@import

@Configuration 注解: 平替bean.xml文件

@ComponentScan 注解: 平替 <context:component-scan base-package="com.frank">

@PropertySource("jdbc.properties") 注解: 平替 <context:property-placeholder location="classpath:jdbc.properties">

@Import(MyDataSource.class)注解:平替 <import resource="classpath:">

注意:

bean.xml文件都被配置类给替换了,那么我在写测试类创建容器对象的时候就不能用

new ClassPathXmlApplicationContext(“bean.xml”)了;而是选择使用new AnnotationConfigApplicationContext(SpringConfig.class)。


demo(实例)

person 类

package fs.exerise;

import org.springframework.stereotype.Component;
 @Component("person")
public class Person {
}

扫描所写注解的类

package fs.exerise;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
// @Configuration 注解表示当前类是一个配置类,用来代替xml配置文件
@Configuration
// @ComponentScan 注解表示扫描包,用来代替xml配置文件
// basePackages 属性表示扫描的包
@ComponentScan(basePackages ="fs.exerise")
public class SpringConfigration {
}

Test 测试类

package fs.exerise;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class test {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfigration.class);
        Object bean = context.getBean("person");
        System.out.println(bean);
    }
}

效果展示

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

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

相关文章

【Linux】多线程 -> 从线程概念到线程控制

线程概念 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行&#xff0c;本质是在进程地址空间内运行。在Linux系统中&#xff0c;在CPU眼…

mapbox 从入门到精通 - 目录

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;mapbox 从入门到精通 文章目录 一、&#x1f340;总目录1.1 ☘️ mapbox基础1.2 ☘️…

深度学习在半导体领域的创新点研究

摘要&#xff1a;本论文聚焦于深度学习在半导体领域的创新应用&#xff0c;全面剖析其为半导体产业带来的变革与机遇。通过深入探究深度学习在半导体设计、制造、测试及质量管控等多方面的创新实践&#xff0c;揭示其对提升半导体性能、降低成本及增强产业竞争力的关键作用。同…

谈谈云计算、DeepSeek和哪吒

我不会硬蹭热点&#xff0c;去分析自己不擅长的跨专业内容&#xff0c;本文谈DeepSeek和哪吒&#xff0c;都是以这两个热点为引子&#xff0c;最终仍然在分析的云计算。 这只是个散文随笔&#xff0c;没有严谨的上下游关联关系&#xff0c;想到哪里就写到哪里。 “人心中的成见…

分享 UniApp 实现列表长按删除功能

在移动应用开发中&#xff0c;列表是常见的展示形式&#xff0c;而长按删除列表项也是一个实用且常见的交互功能。今天就来和大家分享如何在 UniApp 中实现列表的长按删除功能&#xff0c;同时附上详细的代码。 效果预览 通过代码实现后&#xff0c;我们将得到一个带有红色边…

k8s集群搭建参考(by lqw)

文章目录 声明配置yum源安装docker安装 kubeadm&#xff0c;kubelet 和 kubectl部署主节点其他节点加入集群安装网络插件 声明 由于看了几个k8s的教程&#xff0c;都存在各种问题&#xff0c;自己搭建的时候&#xff0c;踩了不少坑&#xff0c;最后还是靠百度csdnchatGPT才搭建…

「前端面试宝典」 - 猿媛之家(21.06)

模拟面试是提高个人沟通技巧的最有效方式 请记住&#xff1a;思维的深度&#xff0c;决定你人生的高度。胸怀的广度&#xff0c;决定你事业的长度。 面试官关注的重点不是题目的答案&#xff0c;而是求职者解题的思路与方法. 以排序算法为例&#xff1a;时间利用是否高效&#…

C++算法竞赛基础语法-9

快速排序是一种高效的排序算法&#xff0c;由C. A. R. Hoare在1960年提出&#xff0c;基本思想是分治法&#xff08;Divide and Conquer&#xff09;策略&#xff0c;通过递归将一个大问题分解为若干个较小的子问题&#xff0c;然后合并这些子问题的解来解决原始问题 快速排序…

Mac安装JD-GUI

Mac安装反编译工具步骤如下&#xff1a; 打开官网https://java-decompiler.github.io/ 选择下载mac的安装包解压下载好的压缩包&#xff0c;点击JD-GUI安装 有可能会遇到如下错误。请先检查是否安装JDK&#xff0c;通过java -version命令查看是否是1.8版本的jdk如果jdk没问题&…

Nginx--日志(介绍、配置、日志轮转)

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 一、Nginx日志介绍 nginx 有一个非常灵活的日志记录模式&#xff0c;每个级别的配置可以有各自独立的访问日志, 所需日志模块 ngx_http_log_module 的…

QML 快捷键与Shortcut的使用

一、效果展示 二、源码分享 import QtQuick import QtQuick.Controls import Qt.labs.qmlmodels import QtQuick.Controls.Basic import QtQuick.Layouts import QtQuick.Effects import Qt.labs.platformApplicationWindow {id:rootwidth: 1000height: 730visible: truetitle…

制造业物联网的十大用例

预计到 2026 年&#xff0c;物联网制造市场价值将达到 4000 亿美元。实时收集和分析来自联网物联网设备与传感器的数据&#xff0c;这一能力为制造商提供了对生产流程前所未有的深入洞察。物联网&#xff08;IoT&#xff09;有潜力彻底改变制造业&#xff0c;使工厂能够更高效地…

考研操作系统----操作系统的概念定义功能和目标(仅仅作为王道哔站课程讲义作用)

目录 操作系统的概念定义功能和目标 操作系统的四个特征 操作系统的分类 ​编辑 操作系统的运行机制 系统调用 操作系统体系结构 操作系统引导 虚拟机 操作系统的概念定义功能和目标 什么是操作系统&#xff1a; 操作系统是指控制和管理整个计算机系统的软硬件资源&…

[极客大挑战 2019]Havefun1

[极客大挑战 2019]Havefun1 代码审计发现 根据代码逻辑&#xff0c;要求传入’cat’参数&#xff0c;值为’dog’时执行if的操作&#xff0c;所以构造参数: ?catdog获得flag

MG协议转换器:破解暖通设备通讯壁垒的智能钥匙

在智能化楼宇管理中&#xff0c;暖通空调系统&#xff08;HVAC&#xff09;的高效运行直接影响建筑的能耗控制与用户体验。然而&#xff0c;暖通设备品牌众多、协议不统一的问题长期困扰着运维人员&#xff1a;不同厂商的冷水机组、风机盘管、传感器等设备因采用Modbus、BACnet…

【赵渝强老师】Spark的容错机制:检查点

由于Spark的计算是在内存中完成&#xff0c;因此任务执行的生命周期lineage&#xff08;血统&#xff09;越长&#xff0c;执行出错的概念就会越大。Spark通过检查点Checkpoint的方式&#xff0c;将RDD的状态写入磁盘进行持久化的保存从而支持容错。如果在检查点之后有节点出现…

算法兵法全略(译文)

目录 始计篇 谋攻篇 军形篇 兵势篇 虚实篇 军争篇 九变篇 行军篇 地形篇 九地篇 火攻篇 用间篇 始计篇 算法&#xff0c;在当今时代&#xff0c;犹如国家关键的战略武器&#xff0c;也是处理各类事务的核心枢纽。算法的世界神秘且变化万千&#xff0c;不够贤能聪慧…

react传递函数与回调函数原理

为什么 React 允许直接传递函数&#xff1f; 回调函数核心逻辑 例子&#xff1a;父组件控制 Modal 的显示与隐藏 // 父组件 (ParentComponent.tsx) import React, { useState } from react; import { Modal, Button } from antd; import ModalContent from ./ModalContent;co…

多媒体术语扫盲备忘录

DRM DRM: Digital Rights Management, 数字版权保护。 广义上讲&#xff0c;能够保护数字版权(不单单是音视频)都可以叫做DRM。 国外主要分为三大类&#xff0c; Google的Widevine, MicroSoft的 PlayReady, 以及 Apple的 FairPlay. 更多细节请参考此文章. Google Widevine: …

盛铂科技 SMF106 低相位噪声贴片式频率综合器模块

在现代通信和电子设备领域&#xff0c;频率综合器作为关键组件&#xff0c;其性能优劣直接影响系统的整体表现。盛铂科技的 SMF106 低相位噪声贴片式频率综合器&#xff0c;以其卓越的性能和独特设计&#xff0c;成为众多高性能系统的选择。 一、频率覆盖范围广&#xff0c;步进…