• 【Spring框架】6.使用注解开发



    在前面的内容中,如果要使用 bean,总免不了先创建一个 xml 文件,然后写一堆 bean 的标签配置,然后才能使用代码获取要用的 bean,再进行业务逻辑处理。

    下面我们在 Spring 中使用注解进行开发,脱离 xml 文件,废话不多说,先来新建一个项目。

    1. 新建项目

    1.1 开发环境

    • IDEA
    • Spring 5.3.20
    • maven 3.6.3

    使用 maven 新建一个 module ,名称是 02-spring-annotation-development,接着新建各个目录和文件,整个项目结构如下所示

    在这里插入图片描述

    1.2 各个目录文件内容

    pom.xml 文件

    • 父 pom 文件
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.yuhuofei</groupId>
        <artifactId>spring-study</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>01-spring-ioc</module>
            <module>02-spring-annotation-development</module>
        </modules>
        <dependencies>
            <!--引入spring框架依赖包-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.3.20</version>
                <type>pom</type>
            </dependency>
    
            <!--引入jdbc依赖包-->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>5.3.20</version>
            </dependency>
    
        </dependencies>
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 子 pom 文件
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>spring-study</artifactId>
            <groupId>org.yuhuofei</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>02-spring-annotation-development</artifactId>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    
    
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    config 配置

    • MyConfig.java
    package com.yuhuofei.config;
    
    import com.yuhuofei.pojo.Student;
    import com.yuhuofei.service.CourseForStudent;
    import com.yuhuofei.service.CourseForStudentImpl;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @Description
     * @ClassName MyConfig
     * @Author yuhuofei
     * @Date 2022/6/26 23:40
     * @Version 1.0
     */
    @Configuration
    @ComponentScan("com.yuhuofei")
    public class MyConfig {
    
        @Bean
        public Student getStudent(){
            return new Student();
        }
    
        @Bean
        public CourseForStudent getCourseForStudent(){
            return new CourseForStudentImpl();
        }
    
        @Bean("controllerUse")
        public CourseForStudent getControllerUse(){
            return new CourseForStudentImpl();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    controller

    • CourseForStudentController.java
    package com.yuhuofei.controller;
    
    import com.yuhuofei.service.CourseForStudent;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * @Description
     * @ClassName CourseForStudent
     * @Author yuhuofei
     * @Date 2022/6/26 23:52
     * @Version 1.0
     */
    @Controller
    public class CourseForStudentController {
    
        @Qualifier("controllerUse")
        @Autowired
        private CourseForStudent courseForStudent;
    
        @RequestMapping("/getStudent")
        public void getStudent() {
            courseForStudent.getStudent();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    dao

    • StudentDao.java
    package com.yuhuofei.dao;
    
    /**
     * @Description
     * @InterfaceName CourseForStudent
     * @Author yuhuofei
     * @Date 2022/6/26 23:47
     * @Version 1.0
     */
    public interface StudentDao {
    
        void queryStudent();
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • StudentDaoImpl.java
    package com.yuhuofei.dao;
    
    import org.springframework.stereotype.Repository;
    
    /**
     * @Description
     * @ClassName CourseForStudentImpl
     * @Author yuhuofei
     * @Date 2022/6/26 23:48
     * @Version 1.0
     */
    @Repository
    public class StudentDaoImpl implements StudentDao {
    
        @Override
        public void queryStudent() {
            System.out.println("测试获取学生信息的方法!");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    pojo

    • Student.java
    package com.yuhuofei.pojo;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    
    /**
     * @Description
     * @ClassName Teacher
     * @Author yuhuofei
     * @Date 2022/6/26 23:42
     * @Version 1.0
     */
    @Component
    public class Student {
    
        @Value("小李")
        private String studentName;
        @Value("16")
        private int studentAge;
        @Value("高中物理")
        private String course;
    
        @Override
        public String toString() {
            return "Student{" +
                    "studentName='" + studentName + '\'' +
                    ", studentAge=" + studentAge +
                    ", course='" + course + '\'' +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    service

    • CourseForStudent.java
    package com.yuhuofei.service;
    
    /**
     * @Description
     * @InterfaceName CourseForStudent
     * @Author yuhuofei
     * @Date 2022/6/26 23:50
     * @Version 1.0
     */
    public interface CourseForStudent {
    
        void getStudent();
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • CourseForStudentImpl.java
    package com.yuhuofei.service;
    
    import com.yuhuofei.dao.StudentDao;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * @Description
     * @ClassName CourseForStudentImpl
     * @Author yuhuofei
     * @Date 2022/6/26 23:50
     * @Version 1.0
     */
    @Service
    public class CourseForStudentImpl implements CourseForStudent {
    
        @Autowired
        private StudentDao student;
    
        @Override
        public void getStudent() {
            student.queryStudent();
        }
    
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    test

    • MyTest.java
    import com.yuhuofei.config.MyConfig;
    import com.yuhuofei.pojo.Student;
    import com.yuhuofei.service.CourseForStudentImpl;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * @Description
     * @ClassName MyTest
     * @Author yuhuofei
     * @Date 2022/6/26 23:39
     * @Version 1.0
     */
    public class MyTest {
    
        public static void main(String[] args) {
    
            ApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
    
            Student student = context.getBean("getStudent", Student.class);
            System.out.println(student);
    
            System.out.println("===================分隔线======================");
    
            CourseForStudentImpl student1 = context.getBean("getCourseForStudent", CourseForStudentImpl.class);
            student1.getStudent();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    1.3 运行测试方法

    运行测试类中的 main 方法,得到的结果,如下所示,正确的输出了在代码中指定的内容

    在这里插入图片描述

    2. 内容分析

    在上面的项目中,可以看到,没有一个注册 bean 的 xml 文件,这说明上面的项目,完全脱离了之前的配置方式,达到了使用注解开发的目的。虽然形式变了,但是主要的内容,却是一样的。

    2.1 配置形式的改变

    之前,如果我们需要使用 bean,会先在一个 beans.xml 文件中使用 bean 的标签,配置一个 bean ,然后再获取它来使用。

    现在,去掉了 xml 文件的配置,改成直接在 MyConfig.java 这个类中,进行 bean 的配置。这个类中用到的三个注解,非常重要,它们决定了能否生成 bean 并托管给 Spring。

    • @Configuration
    • @ComponentScan(“com.yuhuofei”)
    • @Bean

    @Configuration 表示,这是一个配置类,类似于新建的一个 beans.xml 文件

    @ComponentScan(“com.yuhuofei”) 表示,要扫描加载 com.yuhuofei 这个目录下的类,如果不是这个目录下的类,不加载,只有被扫描到,类里面的注解才会生效

    @Bean 表示,这是一个 bean,配置一个 bean ,类似于之前在 beans.xml 文件中写一个 <bean id="student" class="com.yuhuofei.pojo.Student"/>

    2.2 注解的说明

    2.2.1 @Component 的衍生注解
    • @Controller
    • @Repository
    • @Service

    上面三个都是 @Component 的衍生注解,只不过由于在 web 开发中,开发人员喜欢按照 mvc 三层架构进行分层,每一层用不同名称的注解,标注到一个类上,利于区分。

    • dao层:@Repository
    • service层:@Service
    • Controller层:@Controller

    虽然名称不同,但是 @Component 、@Controller、 @Repository、@Service,这四个注解的功能都是一样的,都是表示将某个类注册到 Spring 中,并装配 bean。

    2.2.2 项目中的其它注解
    • @Value
    • @Override
    • @RequestMapping
    • @Autowired
    • @Qualifier

    @Value 用于属性注入,如上面的 Student.java 类中使用 @Value(“小李”) 将学生名字注入到studentName 这个属性中。

    @Override 用于方法重写,表示子类确定重写了父类的方法。

    @RequestMapping 用于启动服务后,对外暴露方法或者说接口的请求路径,例如 @RequestMapping(“/getStudent”),告诉外部,请求 localhost:8080/getStudent ,就能调用到 public void getStudent() 方法。

    另外的两个,之前的博文有提及,这里不再赘述。

    3. 总结

    xml 与注解

    • xml 更加万能,适用于任何场合,维护简单方便
    • 注解,不是自己的类,使用不了,维护相对复杂

    xml 与 注解 实践经验

    • xml 更多是用来管理 bean
    • 注解更多是用来完成属性的注入

    注意点

    在使用过程中,要使注解生效,就要开启注解的支持,一个是指定扫描的包路径,另外一个是注解配置

    • 如果是使用 xml 文件
    <context:component-scan base-package="com.yuhuofei"/>
    <context:annotation-config/>
    
    • 1
    • 2
    • 如果是使用配置类
    @Configuration
    @ComponentScan("com.yuhuofei")
    
    • 1
    • 2
  • 相关阅读:
    二十、泛型(1)
    【DevOps】Rundeck以及Jenkins
    RPC和HTTP的理解
    异步复位同步释放与同步复位打拍
    ubuntu 22.04 安装 minikube 和 istio
    github加速clone
    信息化发展55
    索引背后的数据结构——B+树
    学生Dreamweaver静态网页设计 基于HTML+CSS+JavaScript制作简食餐厅美食网站制作
    SpringBoot面试题5:SpringBoot Starter的工作原理是什么?
  • 原文地址:https://blog.csdn.net/Crezfikbd/article/details/125494076