Spring 原始注解详解与实战指南

news/2025/2/26 8:56:44

📝 1. 前言

在 Spring 框架的发展过程中,注解的引入大大简化了配置,提升了开发效率

本文将详细介绍 Spring 最初引入的核心注解,包括 @Component@Controller@Service@Repository@Autowired@Qualifier@Value 等,结合代码示例演示如何使用这些注解构建一个简单的 Spring 项目


📚 2. Spring 核心原始注解说明表格

注解作用适用场景
@Component标记为 Spring 容器中的 Bean,由 Spring 自动管理通用组件类
@Controller标识控制层组件,处理用户请求MVC 模式中的控制器
@Service标识业务逻辑层组件Service 层实现业务逻辑
@Repository标识数据访问层组件,提供数据库操作异常的转换DAO 层实现数据库访问
@Autowired自动注入 Bean,省去手动实例化属性、构造器、方法注入
@Qualifier指定多个同类型 Bean 中具体要注入的 Bean消除 @Autowired 注入多个 Bean 的歧义
@Value为属性注入配置文件中的值或默认值application.properties 文件读取配置

💻 3. 实战项目:用户信息管理系统

3.1 项目结构

spring-annotation-demo
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com.alivinfer
│   │   │       ├── config
│   │   │       │   └── AppConfig.java
│   │   │       ├── controller
│   │   │       │   └── UserController.java
│   │   │       ├── service
│   │   │       │   └── UserService.java
│   │   │       └── dao
│   │   │           └── UserDao.java
│   │   ├── resources
│   │   │   ├── application.properties
│   │   │   └── logback.xml
└── pom.xml

✅ 3.2 代码实现

1) Spring 配置类
java">import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(basePackages = "com.alivinfer")
public class AppConfig {
}

2) 数据访问层
java">import org.springframework.stereotype.Repository;

@Repository
public class UserDao {
    public String findUserById(int id) {
        return "User_" + id;
    }
}

3) 业务逻辑层
java">import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public String getUser(int id) {
        return userDao.findUserById(id);
    }
}

4) 控制层
java">import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {

   private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;

    public void showUser(int id) {
        logger.info("调用 showUser 方法,用户ID: {}", userService.getUser(id));
        logger.debug("这是调试级别的日志信息");
        System.out.println("执行具体的业务" + userService.getUser(id));
    }
}

5) 启动类
java">import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
   		// 创建 Spring 应用程序上下文(使用反射技术)
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 获取 bean 实例
        UserController userController = context.getBean(UserController.class);

        userController.showUser(1);
        
        // 关闭应用程序上下文,释放所有资源
        context.close();
    }
}

6) logback.xml - 日志配置文件
<configuration>
    <!--定义日志的输出方式为控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--定义日志输出格式-->
        <encoder>
         <!--   %d{yyyy-MM-dd HH:mm:ss}  - 日志输出时间,格式为年-月-日 时:分:秒
            [%thread]                - 输出日志的线程名称,放在方括号内
            %-5level                 - 日志级别,左对齐,宽度为5个字符(例如 INFO、DEBUG)
            %logger{36}              - 打印日志所属的类名,最长36个字符,超出会截断
            %msg                     - 日志的具体信息
            %n                       - 换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!--根日志记录器,所有未被特定 <logger> 匹配的日志都会使用此配置-->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>

    <!--针对特定包或类设置日志级别,优先级高于 <root>-->
    <!--additivity="false":关闭日志向上级传播,避免重复输出-->
    <logger name="com.alivinfer" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE" />
    </logger>
</configuration>
🔥 日志级别优先级
TRACE < DEBUG < INFO < WARN < ERROR
  • 日志级别设置为 INFO,则 DEBUGTRACE 不会输出
  • 特定 logger 可以单独设置更低的日志级别,例如 DEBUG

✅ 3.3 Maven 依赖

 <dependencies>
     <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-context</artifactId>
         <version>6.1.14</version>
     </dependency>

     <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-classic</artifactId>
         <version>1.5.16</version>
     </dependency>

     <dependency>
         <groupId>ch.qos.logback</groupId>
         <artifactId>logback-core</artifactId>
         <version>1.5.16</version>
     </dependency>

     <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-api</artifactId>
         <version>2.0.16</version>
     </dependency>
</dependencies>

🧩 4. 执行结果

2025-02-25 22:58:06 [main] INFO  c.a.controller.UserController - 这是 INFO 级别的日志信息
2025-02-25 22:58:06 [main] DEBUG c.a.controller.UserController - 这是 DEBUG 级别的日志信息
执行具体的业务: User_1

🕶️ 5. 总结

Spring 原始注解@Component@Controller@Service@Repository@Autowired 等,使得开发更加高效、可读性更强。通过这些注解,我们可以实现组件自动扫描、依赖注入和配置管理,减少繁琐的 XML 配置,极大地提升开发体验 😊!


http://www.niftyadmin.cn/n/5868432.html

相关文章

面试之《react近几个版本的更新要点》

React 16.x 系列 React 16.0 Fiber 架构&#xff1a;引入了全新的 Fiber 协调器&#xff0c;解决了旧版同步渲染长时间阻塞主线程的问题&#xff0c;实现了异步可中断渲染、优先级调度、时间分片等特性&#xff0c;大大提升了大型应用的性能和响应能力。 新的错误边界&#x…

【愚公系列】《Python网络爬虫从入门到精通》033-DataFrame的数据排序

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

[Web 安全] PHP 反序列化漏洞 —— PHP 序列化 反序列化

关注这个专栏的其他相关笔记&#xff1a;[Web 安全] 反序列化漏洞 - 学习笔记-CSDN博客 0x01&#xff1a;PHP 序列化 — Serialize 序列化就是将对象的状态信息转化为可以存储或传输的形式的过程&#xff0c;在 PHP 中&#xff0c;通常使用 serialize() 函数来完成序列化的操作…

React七Formik

Formik是一个专为React构建的开源表单库。它提供了一个易于使用的API来处理表单状态管理&#xff0c;表单验证以及表单提交。Formik支持React中的所有表单元素和事件&#xff0c;可以很好地与React生态系统中的其他库集成。同时&#xff0c;Formik还提供了一些高级功能&#xf…

github 推送的常见问题以及解决

文章目录 git add 的时候问题1为什么会发生这种情况&#xff1f;Git 的警告含义如何解决&#xff1f;1. **保持 Git 的默认行为&#xff08;推荐&#xff09;**2. **禁用自动转换**3. **仅在工作目录中禁用转换**4. **统一使用 LF&#xff08;跨平台开发推荐&#xff09;** git…

2.25力扣每日一题--设计内存分配器

2502. 设计内存分配器 - 力扣&#xff08;LeetCode&#xff09; 一&#xff1a;JAVA Allocator(int n)函数&#xff1a;类构造器 int allocate(int size, int mID)函数&#xff1a;输入&#xff0c;待插入块的大小size,插入内容mid / 输出&#xff0c;插入位置块的起始位置…

【redis】数据类型之Bitfields

Redis的Bitfields&#xff08;位域&#xff09;与Bitmaps一样&#xff0c;在Redis中并不是一种独立的数据类型&#xff0c;而是一种基于字符串的数据结构&#xff0c;用于处理位级别的操作。允许用户将一个Redis字符串视作由一系列二进制位组成的数组&#xff0c;并对这些位进行…

Linux 基本开发工具的使用(yum、vim、gcc、g++、gdb、make/makefile)

文章目录 Linux 软件包管理器 - yum理解什么是软件包和yum如何查看/查找软件包如何安装软件如何实现本地机器和云服务器之间的文件互传如何卸载软件 Linux 编辑器 - vim 的使用vim 的基本概念vim 的基本操作vim 命令模式各命令汇总vim 底行模式各命令汇总vim 的简单配置 Linux …