SpringBoot入门篇


一、Maven项目

  1. 创建Maven项目,并勾选web开发相关依赖。
  2. 定义HelloController类,添加方法hello,并添加注解。
  3. 运行测试。

这里使用2020的Idea来演示

创建Mavent项目

从File中创建一个新的模块。

在这里插入图片描述

选中模块中的Spring Initializr,并勾选自己的JDK版本。

在这里插入图片描述

下一步后修改自己的组织名字,把Type中的默认值设置为Maven,语言设置为Java,JDK版本该为自己的JDK版本。

在这里插入图片描述

点击下一步后来到以下的界面,勾选所需要的依赖,设置Springboot的稳定版本2.7。

在这里插入图片描述

基本信息到这就修改结束了,点击完成进行创建(需要网络)。

定义HelloController类,添加方法hello,并添加注解。。

完成创建后,系统会自动生成一个类。

在这里插入图片描述

这个类是测试类,用来启动Springboot工程。

在这里插入图片描述

创建一个请求处理类:HelloController,完成里面的代码。

在这里插入图片描述

注意:

方法中必须含有@RestController注解,不然此类就不是请求处理类。

这时候回到测试类,启动Springboot工程(运行main方法)。

在这里插入图片描述

找到端口号8080,并在浏览器中运行,输入localhost:8080/hello(/hello为请求路径),浏览器会返回一个Hello World。(这里用的是微软的Edge浏览器)

在这里插入图片描述

至此,Springboot的入门演示就此结束。


二、HTTP协议

将上节的localhost:8080/hello 网址复制到记事本中,会看到记事本中开头自动添加了 http://
这就是http协议。

在这里插入图片描述


2.1、协议概述

HTTP(Hyper Text Transfer Protocol):超文本传输协议,规定了浏览器和服务器之间数据传输的规则。

如下图所示,HTTP规定了请求数据与响应数据的格式。

在这里插入图片描述

  • HTTP的特点
    1. 基于TCP协议:面向连接,安全。
    2. 基于请求(响应模型)的:一次请求对应一次响应。
    3. HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求(响应)都是独立的。
      • 缺点:多次请求间不能共享数据
      • 优点:速度快。

2.2、请求协议

HTTP—请求数据格式

  • 请求行:

请求数据第一行(请求方式、资源路径、协议)

  • 请求头:

第二行开始,格式为:key:value的键值对方式。

  • 请求体:

POST请求,存放请求参数。

注意:

请求方式有两种:GET与POST。

  • GET:请求参数在请求行中,没有请求体,如:/brand/findAll?name=OPPO&status=1。(GET请求大小是有限制的
  • POST:请求参数在请求体中,POST请求大小是没有限制的

如下图所示,绿色为请求行,蓝色为请求头。

在这里插入图片描述

上图中的数据含义如下表所示。

单词所属含义
Host请求的主机名
User - Agent浏览器版本,例如Chrome浏览器的标识类似Mozilla/5.0 …Chrome/79。
Accept表示浏览器能接收的资源类型,如 text/* ,image/* 或者*/*表示所有 。
Accept - Language表示浏览器偏好的语言,服务器可以据此返回不同语言的网页。
Accept - Encoding表示浏览器可以支持的压缩类型,例如gzip,deflate等。
Content-Type请求主体的数据类型。
Content - Length请求主体的大小(单位:字节)。

2.3、响应协议

HTTP—请求数据格式

在这里插入图片描述

响应状态码的分类

状态码格式所属含义
1xx响应中—临时状态,表示请求已经接收,告诉客户端应该继续请求或者如果它已经完成则忽略它。
2xx成功—表示请求已经被成功接收,处理已完成。
3xx重定向—重定向到其他地方;让客户端再发起一次请求以完成整个处理。
4xx客户端错误—处理发生错误,责任在客户端。如:请求了不存在的资源,客户端未被授权、禁止访问等。
5xx服务器错误—处理发生错误,责任在服务器。如:程序抛出异常等。

常见响应状态码

在这里插入图片描述

最常用的三个响应状态码(☆)

状态码含义
200客户端请求成功。
404请求资源不存在,一般是URL输入有误,或者网站资源被删除。
500服务器发生不可预期的错误。

常见响应头

响应头所属含义
Content-Type表示该响应内容的类型,例如:text/html,application/json。
Content-Length表示该响应内容的长度(字节数)。
Content-Encoding表示该响应压缩算法,例如gzip。
Cache-Control指客户端应如何缓存,例如max-age=300表示可以最多缓存300秒。
Set-Cookie告诉浏览器为当前页面所在的区域设置cookie。

2.3、协议解析

目前协议解析最流行的4大厂商:

  1. jetty://
  2. WebLogic
  3. WebSphere
  4. Apache Tomcat

它们把http协议解析后封装成一个服务器,供人们使用。


三、Web服务器 -TomCat

3.1、Tomcat简介

Web服务器:一个软件程序,对HTTP协议的操作进行封装,使得程序员不必直接对协议进行操作,让Web开发更加便捷。主要功能是"提供网上信息浏览服务"。

Tomcat: Apache软件基金会一个核心项目,支持Servlet/JSP少量JavaEE规范,是一个开源免费的轻量级Web服务器。

  • JavaEE包含13项技术规范:JDBC、JNDI、EJB、RMI、JSP、Servlet、XML、JMS、Java IDL、JTS、JTA、JavaMail、JAF。

  • Tomcat也被称为Web容器、Servlet容器。Servlet程序需要依赖于Tomcat才能运行。

在这里插入图片描述

小结:

Web服务器

  • 对HTTP协议操作进行封装,简化web程序开发。
  • 部署web项目,对外提供网上信息浏览服务。

Tomcat

  • 一个轻量级的web服务器,支持servlet、jsp等少量javaEE规范。
  • 也被称为web容器、servlet容器。

3.2、Tomcat使用

  • 下载
    https://tomcat.apache.org/download-90.cgi
  • 安装
    直接解压。
  • 卸载
    直接删除目录即可。
  • 启动
    双击:bin\startup.bat
  • 停止
    • 直接 x掉运行窗口:强制关闭。
    • bin\shutdown.bat:正常关闭。
    • Ctrl+C:正常关闭。
  • 部署
    将项目放置到webapps目录下,即部署完成。

Tomcat文件目录

在这里插入图片描述

安装Tomcat常见问题

  • 控制台中文乱码

修改conf/logging.properties

在这里插入图片描述

  • 启动窗口一闪而过

检查JAVA_HOME环境变量是否正确配置。

在这里插入图片描述

  • 端口号冲突

找到对应程序,将其关闭掉(一般idea可能会占用8080)

配置Tomcat端口号(conf/server.xml)

在这里插入图片描述

注意:

HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号。

3.3、内嵌Tomcat

在Springboot中,不需要我们自己手动配置tomcat,它的里面嵌有tomcat(红色背景的依赖),可以直接使用。

在这里插入图片描述

起步依赖

  • spring-boot-starter-web。
  • spring-boot-starter-test。

内嵌Tomcat服务器

  • 基于Springboot开发的web应用程序,内置了tomcat服务器,当启动类运行时,会自动启动内嵌的tomcat服务器。

四、请求响应

浏览器与后台的数据传输,是靠着前端控制器(DispatcherServlet) 来接收请求与响应的。

而前端控制器中有着两个对象:

  • 请求(HttpServletRequest):获取请求数据。
  • 响应(HttpServletResponse):获取响应数据

这种传输的模式被称为:BS架构。

BS架构:Browser / Server,浏览器 / 服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。

BS架构的典型应用:京东、淘宝、天猫、唯品会等。

还有一种基于客户端和服务器进行数据传输的架构叫做:CS架构。

CS架构:Client / Server,客户端 / 服务器架构模式

CS架构的典型应用:微信、QQ等。

两种架构的优缺点

  1. BS架构:维护方便、体验一般。
  2. CS架构:开发、维护麻烦,体验较佳。

4.1、请求

4.1.1、postman

postman:一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。

在这里插入图片描述

作用:常用语进行接口测试。

postman的安装不需要自己手动操作,双击安装包等待即可(需要网络),注册并进入软件。

postman操作界面介绍

创建文件

  1. 创建工作空间
    在这里插入图片描述

  2. 设置名字以及权限

在这里插入图片描述

  1. 输入网址及其保存测试文件。

在这里插入图片描述

总界面参数功能

在这里插入图片描述


4.1.2、简单参数

原始方法:在原始的web程序中,获取请求参数,需要通过HttpServletRequest对象手动获取。

创建新的测试类

在这里插入图片描述

在postman中测试,并加入数据

在这里插入图片描述
在idea中查看添加的值

在这里插入图片描述

这种原始方式来传递数据是非常繁琐的,而且需要手动类型转换,所以这种方式已经被淘汰了,有了新的方式:SpringBoot方式。


SpringBoot方式

简单参数:参数名与形参变量名相同,定义形参即可接收参数。

修改过后的测试类为:

在这里插入图片描述

得到的值依旧是Tom:10

在这里插入图片描述


在postman中使用post请求。

在这里插入图片描述

得到的结果依旧是Tom:10

在这里插入图片描述


如果使用post请求遇到形参与实参名不相匹的情况,idea端不会报错,只会把不匹配的参数值设置为null。

在这里插入图片描述

在这里插入图片描述

那如何避免这种情况的发生?

这时候就需要用到新的注解:@RequestParam 来防止这种情况的发生。

在这里插入图片描述

这个时候再去运行,就不会出现空值的情况了。

在这里插入图片描述
idea

在这里插入图片描述


但是添加这种注解还有个问题,那就是如果我没有添加user的值,那么程序又会怎么样?

在这里插入图片描述

可以看到,我取消了name的传递,postman里报出了400的错误,那么idea客户端呢?

在这里插入图片描述

idea客户端并没有出error,而是变成了黄色的waring,并且值也没有输出在console中。

出现这种警告的原因是:在@requestParam中有一个叫required的属性,默认为true,这个属性所代表的意思为:代表该请求参数必须传递,如果不传递将报错。

但是该参数是可选的,可以将required属性设置为false,这样就可以防止少穿参数而出现警告。

测试类

在这里插入图片描述

postman

在这里插入图片描述

console

在这里插入图片描述

这样就不会出现红色的error以及黄色的warn,但是会出现null,这是因为并没有传name的属性值。


简单参数小结

  1. 原始方式获取请求参数

    • Controller方法形参中声明HttpServletRequest对象。
    • 调用对象的getParameter(参数名)。
  2. SpringBoot中接收简单参数

    • 请求参数名与方法形参变量名相同。
    • 会自动进行类型转换。
  3. @RequestParam注解

    • 方法形参名称与请求参数名称不匹配,通过该注解完成映射。
    • 该注解的required属性默认是true,代表请求参数必须传递。

4.1.3、实体参数

简单实体对象:请求参数名与形参对象属性名相同,定义POJO接收即可。

测试类(封装形参,传递对象)

在这里插入图片描述

在postman中传参,在idea中Console显示传入的值。

在这里插入图片描述


复杂实体对象:请求参数与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数。

测试类参数不变,依旧是User user,User类多了个Address的参数。

User类

在这里插入图片描述

Address类

在这里插入图片描述
在postman中使用get请求,在simplePojo后加上参数:

name=Tom&age=23&address.province="北京"&address.city="北京";

注意:

这里嵌套的address对象中的值是以address.属性名来传递值的。

在这里插入图片描述

Console:

在这里插入图片描述

在Console中完整的展现出User的值。

小结:

请求参数名与形参对象属性名相同,即可直接通过POJO接收。


4.1.4、数组集合参数

数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数。

在测试类中的形参改为数组,并调用Arrays中的toString来输出数组。

在这里插入图片描述

在postman中添加数组内容

在这里插入图片描述

在Console中得到结果

在这里插入图片描述


集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam绑定参数关系。

在测试类中修改形参为集合,并在方法中输出。

Console:

在这里插入图片描述

注意:

在使用集合参数时,必须在形参中添加@RequestParam,否则在postman中会报error:500,在Console中会出现error。

在这里插入图片描述


数组集合参数小结

  • 数组:请求参数名与形参中数组变量名相同,可以直接使用数组封装。
  • 集合:请求参数名与形参中集合变量名相同,通过@RequestParam绑定参数关系。

4.1.5、日期参数与JSON参数

日期参数:使用 @DateTimeFormat 注解完成日期参数格式转换。

测试类的形参改为日期对象,添加@DateTimeFormat注解,并设置格式(pattern = "yyyy-MM-dd HH:mm:ss")

在这里插入图片描述

在postman中使用gei方式传输数据。

在这里插入图片描述


JSON参数:JSON数据键名与形参属性名相同,定义POJO类型形参即可接收参数,需要使用@RequestBody标识符。

测试类修改成对象形参,添加@RequestBody注解。

在这里插入图片描述
注意:要在postman中传递JSON格式的数据,要选择 Body 中的 raw,再在后面选择JSON格式。

在这里插入图片描述


4.1.6、路径参数

路径参数:通过请求URL直接传递参数,使用 {…} 来标识该路径参数,需要使用 @PathVariable 获取路径参数。

测试类中修改形参类型,使用 @PathVariable 注解,注:每一个参数前都要有一个注解。
在这里插入图片描述

在postman中传入参数,通过path/值1/值2来传递。

在这里插入图片描述


4.1.7、请求参数总结

  • 简单参数:需要通过@RequestParam注解来手动映射。
  • 集合参数:需要通过@RequestParam注解来绑定关系。
  • 日期参数:需要添加DateTimeFormat注解。
  • JSON参数:需要添加RequestBody注解。
  • 路径参数:需要添加@PathVariable注解。

在这里插入图片描述


4.2、响应

4.2.1、@ResponseBody与统一响应

@ResponseBody

  • 类型:方法注解、类注解。
  • 位置:Controller方法上/类上。
  • 作用:将方法返回值直接响应,如果返回值类型是 实体对象 / 集合,将会转换为JSON格式响应。
  • 说明: @ResController = @Controller + @ResponseBody;

现在在测试类中定义三个方法,接收与返回的值分别为:字符串、对象、集合。
在这里插入图片描述

当我传入的参数是hello时,那么调用的就是第一个方法,并返回Hello World。

在这里插入图片描述

Console

:


同样的,如果我传入的是listAddr,那么调用的则是第三个方法。

在这里插入图片描述

这样如果一个个返回新的值,调用不同特有方法,是解析繁琐,且难以维护的,所以就有了统一响应结果的方式。

统一响应结果

创建一个新的类Result,里面创建属性,分别是:

code:表示成功或者失败。
msg:提示成功或失败。
data:接收传输数据。

且在测试类中创建success的静态方法,传递数据,并且在Result类中添加get、set方法、toString方法、构造器。

在这里插入图片描述

这时再去改造测试类。

hello方法

在这里插入图片描述

getAddr方法

在这里插入图片描述

listAddr方法。

在这里插入图片描述

这三个方法都通过Result类改造完成,且返回的值都是通过Result.success()来获得,调用的方式并没有改变,这样就规范响应的统一格式,意义是:方便前端人员的维护以及修改。

在这里插入图片描述


@ResponseBody与统一响应结果小结

  1. @ResponseBody

    • 位置:Controller类 上/ 方法上。
    • 作用:将方法返回值直接响应,若返回值类型是 实体对象 / 集合,转JSON格式响应。
  2. 统一响应结果
    - Result(code、msg、data)


4.2.2、响应案例

现在的需求是:要获取员工数据,返回统一响应结果,在页面渲染展示。

完成的步骤:

  • 在pom.xml文件中引入dom4j的依赖,用于解析XML文件。
  • 引入资料中提供的解析XML的工具类XMLParserUtils、对应的实体类Emp、XML文件emp.xml。
  • 引入资料中提供的静态页面文件,放在resource下的static目录下。
  • 编写Controller程序,处理请求,响应数据。

现在开始按步骤完成

在xml文件中引入dom4j,这里引入的时候会报红,刷新mavn即可自动导入相应的包。

在这里插入图片描述

创建utils包,并导入一个解析XML的工具类XMLParserUtils。

在这里插入图片描述

在pojp包中导入Emp实体类。

在这里插入图片描述

在resource中导入一个xml文件。

在这里插入图片描述

在resource中static目录下引入前端页面。

在这里插入图片描述

在Controller类中编写程序,处理请求,响应数据。

package com.test.controller;

import com.test.pojo.Emp;
import com.test.pojo.Result;
import com.test.utils.XmlParserUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class HelloController {
    @RequestMapping("/listEmp")
    public Result list(){
        //1.加载 emp.xml 并解析 emp.xml中的数据
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);

        //2.对员工信息中的gender,job字段进行处理
        empList.stream().forEach(emp -> {
            String gender = emp.getGender(); //gender: 1 男 2 女
            if("1".equals(gender)){
                emp.setGender("男");
            }else if ("2".equals(gender)){
                emp.setGender("女");
            }

            String job = emp.getJob(); //job : 1 讲师 2 班主任 3 导员
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("导员");
            }
        });

        //3.组装数据并返回
        return Result.success(empList);
    }
}

在postman中测试

在这里插入图片描述

运行成功。

注意事项:

SpringBoot项目的静态资源(html、css、js等前端资源)默认存放目录为:classpath:/static、classpath:/public、classpath:/resources。


4.3、分层解耦

在上一个案例中,Controller类集合了对xml的解析、对字段的处理、数据的返回,虽然上个案例的代码很少,也很简单,但是在以后遇到的复杂项目中会变得难以维护,复用性差,所以有了一个新的东西来优化这个问题。

4.3.1、三层架构

Controller类中的代码可以分成如下的三个模块:

在这里插入图片描述

每个模块的职责单一,分别处理不同的需求,这样的优势就是不用进行全局修改,可以局部调整,而不去影响其他的模块。

三层架构

  • controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
  • service:业务逻辑层,处理具体的业务逻辑。
  • dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增、删、改、查。

在这里插入图片描述

通过三层架构,可以清晰的看到,前后端的交互是:

请求

Controller层接收由浏览器传输过来的请求,再传输给Service层,经过Service层的逻辑处理后再调用dao层,dao层再对文件进行操作(增删改查)。

响应

请求的路径结束完后,由dao层拿到对文件操作后的数据,返回给Service层进行逻辑处理,再返回给Controller,最后由Controller响应数据给前端的浏览器。

这样做的优点是:

假如我要实现业务逻辑的改变,就可以单独修改Service层的逻辑即可,并不需要修改Controller层与dao层的数据,这样项目的可维护性更高。

使用三层架构来改进代码

在这里插入图片描述

Controller层

HelloController类

@RestController
public class HelloController {
    private EmpService empService = new EmpServiceA();
    @RequestMapping("/listEmp")
    public Result list(){
        //1.调用service,获取数据
        List<Emp> empList = empService.listEmp();

        //3.组装数据并返回
        return Result.success(empList);
    }
}

Service层

EmpService接口

public interface EmpService {
    //获取员工列表数据
    public List<Emp> listEmp();
}

EmpServiceA类

public class EmpServiceA implements EmpService {
    private EmpDao empDao = new EmpDaoA();
    @Override
    public List<Emp> listEmp() {
        //1.调用dao,获取数据
        List<Emp> empList = empDao.listEmp();

        //2.对员工信息中的gender,job字段进行处理
        empList.stream().forEach(emp -> {
            String gender = emp.getGender(); //gender: 1 男 2 女
            if("1".equals(gender)){
                emp.setGender("男");
            }else if ("2".equals(gender)){
                emp.setGender("女");
            }

            String job = emp.getJob(); //job : 1 讲师 2 班主任 3 导员
            if("1".equals(job)){
                emp.setJob("讲师");
            }else if("2".equals(job)){
                emp.setJob("班主任");
            }else if("3".equals(job)){
                emp.setJob("导员");
            }
        });

        return empList;
    }
}

dao层

EmpDao接口

public interface EmpDao {
    //获取员工数据列表
    public List<Emp> listEmp();
}

EmpDaoA类

public class EmpDaoA implements EmpDao {
    @Override
    public List<Emp> listEmp() {
        //1.加载 emp.xml 并解析 emp.xml中的数据
        String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
        List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
        return empList;
    }
}

4.3.2、分层解耦

  • 内聚:软件中各个功能模块内部的功能联系。
  • 耦合:衡量软件中各个层 / 模块之间的依赖、关联的程度。
  • 软件设计原则:高内聚,低耦合。

从上小节的代码可以看到,三层结构之间都互有联系,即使修改了一个层级中的机构,还是有可能要修改其他层级的代码,为了防止这种耦合的发生,我们可以在每个层级之间添加一个容器,来作为中间层级,降低它们的耦合关系。

在这里插入图片描述

这时候接触了新的三个概念:

  • 控制反转(IOC):Spring框架的第一大核心。对象的控制权由程序自身转移到外部(容器),这种思想称为控制反转。
  • 依赖注入(DI):容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
  • Bean对象(bean):IOC容器中创建、管理的对象,称之为bean。

4.3.3、IOC & DI

IOC & DI 快速入门

步骤:

  1. Service层 及 Dao层的实现类,交给IOC容器管理。
  2. 为Controller 及 Service注入运行时,依赖的对象。
  3. 运行测试。

如何把Service层 和 Dao层的实现类交给IOC容器?

在实现类上加上@Component注解就可以实现。

如何为Controller 及 Service 注入依赖对象?

在它们的开头加上@Autowired注解就可以实现,在运行时,IOC容器会提供该类型的bean对象,并赋值给该变量(依赖注入)。

  1. Service层 及 Dao层的实现类,交给IOC容器管理。

在这里插入图片描述

  1. 为Controller 及 Service注入运行时,依赖的对象。

在这里插入图片描述

测试

在这里插入图片描述


4.3.4、IOC(控制反转)

控制反转:指将对象的控制权交给IOC容器,由IOC容器来创建和管理这些对象,IOC里的这些对象也被称为Bean对象。

Bean的声明

想要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一:

在这里插入图片描述

注意事项:

  • 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写。
  • 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。

Bean组件扫描

  • 前面声明bean的四大注解,要想生效,还需要被组件扫描注解:@ComponentScan 扫描。
  • @ComponentScan 注解虽然没有显示配置,但是实际上已经包含在了启动类声明注解 @SpringBootApplication 中,默认扫描的范围是启动类所在包及其子包。
ComponentScan({需要扫描的包},{启动类所在包})

小结:

注解的声明

  • @Component,@Controller,@Service,@Repository
  • @SpringBootApplication具有包扫描作用,默认扫描当前包及其子包。

4.3.5、DI(依赖注入)

DI:IOC容器要为应用程序提供运行时所依赖的资源。资源,指的是对象。

Bean注入

  • @Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出如下错误:

在这里插入图片描述

上面出现的错误可以通过以下几种方案来解决:

  • @Primary (设置bean优先级,想用哪个就在哪个上面添加)
  • @Qualifier(@Autowired 配合 @Qualifier 指定注入的是哪个bean)
  • @Resource(指定注入哪个bean,指定bean的名字)

@Primary

@Primary
@Service
public class EmpServiceA implements EmpService{

}

@Qualifier

@RestController
public class EmpController{
	@Autowired
	@Qualifier("empServiceA")
	private EmpService empService;
}

@Resoure

@RestController
public class EmpController{
	@Resource(name = "empServiceB")
	private EmpService empService;
}

小结:

依赖注入的注解

  1. @Autowired:默认按照类型自动装配。
  2. 如果同类型的bean存在多个:
    • @Primary
    • @Autowired + @Qualifie(“bean的名称”)
    • @Resource(name = “bean的名称”)

@Resource 与 @Autowired区别

  • @Autowired 是 spring框架提供的注解,而@Resource是JDK提供的注解。
  • @Autowired 默认是按照类型注入,而@Resource默认是按照名称注入。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值