spring学习:

1.1简介

ssh: struct + spring + Hibernate

ssm: SpringMVC + spring + mybatis

Spring Framework

1
2
3
4
5
6
7
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>

1
2
3
4
5
6
7
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.9</version>
</dependency>

1.2、优点:

  • spring 是一个开源的免费的框架(容器)

  • spring 是一个轻量级的、非入侵式的框架,引入之后不会对原来项目造成影响

    • 控制反转(IOC),面向切面编程(AOP)

    • 支持事务的处理,对框架整合的支持

1.3、拓展 img

核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

  Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。

Spring Boot

  • 一个快速开发的脚手架

  • 基于SpringBoot可以快速的开发单个微服务

  • 约定大于配置

Spring cloud 是基于Spring Boot实现的

现在大多数公司都在使用Springboot进行快速开发

IOC理论推导:

​ 在同一个业务之下,在一个接口之下实现不同的功能,如何在controller层进行控制,而不是,servers修改原来的代码。

就是说,将原来需要程序员在serverce层去创建类的效果转到controller层,每个业务都需要修改程序,而ioc 就是我要什么,就创建什么

业务在平行之间,能够进行动态的选择。

程序员不用去管对象的创建,而是更加的关注于业务 ,主动权交到了用户的手上。

image-20210813220259410

image-20210813220311432

image-20210813220322337

image-20210813220338040

image-20210813220348405

image-20210813220406600

image-20210813220626185

image-20210813220809616

IOC本质:

控制反转是一种思想,依赖注入是实现控制反转的一种方式

loC是Spring框架的核心内容,使用多种方式完美的实现了loC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现loC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从loc容器中取出需要的对象。

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,I而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是loC容器,其实现方法是依赖注入(Dependency Injection,Dl)。

控制: 谁来控制对象的创建,传统的应用程序中对象是由程序本身控制创建的,使用spring之后,对象就是由Spring 来创建的

反转: 程序本身不创建对象,而变成被动的接受对象

依赖注入: 就是利用set方法来进行注入的

所谓的ioc就是对象交给Spring 来创建 管理 装配

DI是实现ioc的一种方式

依赖注入

使用无参构造创建对象:

通过类型创建,下标赋值:

image-20210814194125829

通过类型创建:

image-20210814194147671

直接通过参数名进行创建:

image-20210814194200079

别名:

​ 如果添加了别名,我们也可以使用别名获取这个对象

​ 使用id + class +name 来进行对象之间的创建,;等都可以进行配置

image-20210814195533727

import

​ 这个import,一般用于团队开发 可以将多个配置文件,导入合并为一个文件

​ 假如项目中有多个人进行开发,这三个人复制不同的类进行开发,不同的类需要注册不同的bean,我们可以利用

import将所有人的beans.xml合并为一个总的

​ 使用的时候直接使用总的配置就可以了

image-20210814200239615

image-20210814200309527

set方式注入

  • ​ 依赖注入: set注入

    • 依赖:bean 对象的创建依赖于容器
    • 注入:bean对象的所有属性,由容器来注入

    环境搭建:

    Student:

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    package com.wz.pojo;

    import java.util.*;

    public class Student {

    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;

    public Student() {
    }

    public String getName() {
    return name;
    }

    public Student setName(String name) {
    this.name = name;
    return this;
    }

    public Address getAddress() {
    return address;
    }

    public Student setAddress(Address address) {
    this.address = address;
    return this;
    }

    public String[] getBooks() {
    return books;
    }

    public Student setBooks(String[] books) {
    this.books = books;
    return this;
    }

    public List<String> getHobbys() {
    return hobbys;
    }

    public Student setHobbys(List<String> hobbys) {
    this.hobbys = hobbys;
    return this;
    }

    public Map<String, String> getCard() {
    return card;
    }

    public Student setCard(Map<String, String> card) {
    this.card = card;
    return this;
    }

    public Set<String> getGames() {
    return games;
    }

    public Student setGames(Set<String> games) {
    this.games = games;
    return this;
    }

    public String getWife() {
    return wife;
    }

    public Student setWife(String wife) {
    this.wife = wife;
    return this;
    }

    public Properties getInfo() {
    return info;
    }

    public Student setInfo(Properties info) {
    this.info = info;
    return this;
    }

    @Override
    public String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", books=" + Arrays.toString(books) +
    ", hobbys=" + hobbys +
    ", card=" + card +
    ", games=" + games +
    ", wife='" + wife + '\'' +
    ", info=" + info +
    '}';
    }
    }

    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
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    <?xml version="1.0" encoding="UTF-8"?>
    <!--suppress ALL -->
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd ">
    <!-- 注入bean-->
    <bean id ="address" class="com.wz.pojo.Address"/>
    <bean id ="student" class="com.wz.pojo.Student">

    <!-- 普通值的注入-->
    <property name="name" value="jin"></property>
    <!--第二种,bean注入 ref-->

    <property name="address" ref="address"/>
    <!--数组的注入,ref-->
    <property name="books">
    <array>
    <value>小金</value>
    <value>小聂</value>
    </array>
    </property>
    <!--list注入-->
    <property name="hobbys">
    <list>
    <value>听歌</value>
    <value>敲代码</value>
    <value>看电影</value>
    </list>
    </property>
    <property name="card">
    <map>
    <entry key ="身份证" value="1233"/>
    <entry key="aa" value="1122"/>
    </map>
    </property>

    <property name="games">
    <set>
    <value>lo</value>
    <value>coc</value>
    <value>sss</value>
    </set>
    </property>
    <property name="info">
    <props>
    <prop key="学号">2019</prop>
    <prop key="url">root</prop>
    <prop key="pasword">12333</prop>
    </props>
    </property>
    </bean>

    </beans>

spring MVC:

image-20210826091755443

image-20210826091818396

dispatcherService能够对请求进行分发,不用像servelet区分发请求

image-20210826092428236

image-20210826111216478

image-20210826111500895

url地址映射:

映射单个地址:

使用@RequestMapping(“/”);

可以使用/,也可以不使用

映射多个地址:

image-20211024013109029

设置类路径:

1、设置在方法级别

​ 方法路径

2、设置在类级别上

​ 类路径

3、设置类级别与方法级别

​ 类路经/方法路径

4、设置请求地址的请求方式

使用@ReqestMapping(value=”路径”,method =”post”)

5、设置参数路径

参数绑定:

传递的参数

基本数据类型:

基本数据类型绑定

参数值必须存在。如果没有指定参数值,也没有设置参数默认值,会报500

包装类型

​ 通过注解@RequestParam标记一个形参为请求参数

​ 可以通过注解的属性设置相关的内容

​ 设置参数的默认值 defaultValue

image-20211024111217900

字符串类型

数组类型:

参数名与形参名一致

image-20211024111444388

JavaBean类型:

参数名与JavaBean对象中的属性字段名一致(自动设置到Javabean中)

List类型

List类型

Set类型

Map类型

请求转发与重定向:

请求转发

SpringMVC内部默认采用请求转发形式

请求转发:

地址栏不发生变化

注:默认都会从 视图解析器设置的路径下查找指定视图(不需要设置视图的后缀,直接写视图的名字),如果想使用forward进行查找

重定向:

重定向到jsp页面

默认从项目的根目录下查找 资源

可以传递参数,如果直接传递中文,就无法进行获取,需要使用RedirectAttributest对象来进行设置

image-20211024122050041

image-20211024122118846

五种作用域:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* @author jin
* spring几种作用域
* @date 2021/10/24
* */
@Controller
@RequestMapping("/study")
public class StudyController {

/**
* modelAndView
* addObject
* @return
*/
@RequestMapping("data01")
public ModelAndView data01() {

ModelAndView modelAndView = new ModelAndView("study/data");
//设置请求域
modelAndView.addObject("msg", "通过ModelandView对象设置请求域");
return modelAndView;
}

/**
* 使用 HttpServletRequest 对象设置请求域
* setAttribute
* @param request
* @return
*/
@RequestMapping("data02")
public String data02(HttpServletRequest request) {
request.setAttribute("msg","通过HttpServletRequest 对象设置请求域");
// 指定具体的视图路径
return "study/data";
}

/**
*通过 Model 对象设置请求域
* addAttribute
* @param request
* @return
*/
@RequestMapping("data03")
public String data03(Model request) {
request.addAttribute("msg","通过 Model 对象设置请求域");
return "study/data";
}

/**
* 通过 ModelMap 对象设置请求域
* @param request
* @return
*/
@RequestMapping("data04")
public String data04(ModelMap request) {
request.addAttribute("msg","通过 ModelMap 对象设置请求域");
return "study/data";
}

/**
* 通过 Map 对象设置请求域
*
* @param map
* @return
*/
@RequestMapping("data04")
public String data04(Map map) {
map.put("msg","通过 Map 对象设置请求域");
return "study/data";
}

JSON数据开发:

使用 @ResponseBody:

设置在方法级别 或者方法类型上,默认控制器中方法的返回值是会找对应的视图,如果想要将返回的结果转换为字符串响应

使用 @RequestBody

要求传递的参数一定是json格式的字符串

1
2
3
4
5
6
7
8
9
10
11
<!-- jackson -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
1
2
3
4
5
6
7
@RequestMapping(value="/save.json",method = RequestMethod.POST)
@ResponseBody
public JsonData saveAclModule(AclModelParam param) {
sysAclModuleService.save(param);
return JsonData.success();
}

1
2
3
4
5
6
@RequestMapping("/save.json")
@ResponseBody
public JsonData saveDept( DeptParam deptParam){
System.out.println("deptParam = " + deptParam);
sysDeptService.save(deptParam);
return JsonData.success(); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//请求案例
<script type="text/javascript" >
var user ={"userId":"001"};

$.ajax({
type:"get",
url:"",//请求的url地址
async:true,//异步设置
contentType:"application/json; charset= utf-8",
data:JSON.stringify(user),
dataType:'json',//返回的json数据
//回调函数
success:function (data) {
console.log(data)
}
})

</script>
1
2
3
4
5
@RequestMapping("/update.json")
public JsonData updateDept(@RequestBody DeptParam deptParam){
sysDeptService.update(deptParam);
return JsonData.success();
}

第二部分:

1.拦截器:

2.1.基本概念

SpringMVC 中的 Interceptor拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理。比如通过它来进行权限验证,空参校验等或者是来判断用户是否登陆等操作。对于SpringMVC拦截器的定义方式有两种:

实现接口: org.springframework.web.servlet.HandlerInterceptor

继承适配器: org.springframework.web.servlet.handler.HandlerInterceptorAdapter

1
2
3
<mvc:interceptors>
<bean class="com.dorou.common.HttpInterceptor"/>
</mvc:interceptors>
1
2
3
4
5
6
7
8
   //配置 指定的路由进行拦截
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/sys/**"/>
<bean class="com.dorou.common.HttpInterceptor"/><
</mvc:interceptor>

</mvc:interceptors>
1
实现  :public class HttpInterceptor implements HandlerInterceptor

打印请求的参数:

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
37
38
39
40
41
42
43
44
45
46
    /**
* 在目标方法执行之前执行
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
//请求方法处理之前进行调用,可以用在登录验证、权限验证、参数验证等模块之中
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String url = request.getRequestURI().toString();
Map map = request.getParameterMap();
LOGGER.info("request start. url:{},param:{}", url, JsonMapper.obj2String(map));
Long start = System.currentTimeMillis();
request.setAttribute(START_TIME, start);
return true;
}

//正常结束之后调用该请求,下面两个请求几乎是同时进行请求,所以可以直接注释掉
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// String url = request.getRequestURI().toString();
// Map map = request.getParameterMap();
// Long start= (Long) request.getAttribute(START_TIME);
// Long end = System.currentTimeMillis();
//
// LOGGER.info("request finished. url:{},param:{},cost:{}",url,JsonMapper.obj2String(map),end-start);
removeThreadLocalInfo();
}
//线程结束的时候需要移走线程
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
String url = request.getRequestURI().toString();
Map map = request.getParameterMap();
long start = (Long) request.getAttribute(START_TIME);
long end = System.currentTimeMillis();
LOGGER.info("request complete. url:{},param:{},cost:{}", url, JsonMapper.obj2String(map), end - start);
removeThreadLocalInfo();
}

// 当该线程结束后需要将线程移除
public void removeThreadLocalInfo() {
RequestHolder.remove();
}

2、过滤器区别:

2.1:什么是过滤器

在就Javaweb中,传入的 请求request 、response需要提前过滤一些信息,或者 需要提前设置一些信息或者提前设置一些参数,然后再传入action中进行过滤,比如过滤非法的字符,或者设置统一的字符集

init(FilterConfig filterConfig) :初始化配置的参数

doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)

对拦截的请求进行预处理

destroy()用于资源的回收

2.2过滤器的配置:

过滤 请求配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<!-- 指拦截请求匹配所有的请求 “/”代表拦截所有的亲请求,"*.do"拦截所有,do请求以什么结尾-->
<url-pattern>/*</url-pattern>
</filter-mapping>

2.3: 拦截登录的请求:

1
2
3
4
5
6
7
8
9
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.dorou.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
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
37
38
39
40
41
42
43
44
45
46
47
48
import com.dorou.beans.RequestHolder;
import com.dorou.model.SysUser;
import com.dorou.util.IpUtil;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.LogRecord;

/**
* 拦截用户需要登陆的请求
*/
public class LoginFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}
// 判断是否在登陆中
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req =(HttpServletRequest)servletRequest;
HttpServletResponse resp = (HttpServletResponse) servletResponse;
SysUser sysUser = (SysUser)req.getSession().getAttribute("user");

System.out.println("sysUser = " + sysUser);

//// 如果用户没有进行登录
// if (sysUser == null) {
// String path = "/signin.jsp";
// resp.sendRedirect(path);
// return;
// }、
System.out.println(IpUtil.getRemoteIp(req));

// 已经进行登录
RequestHolder.add(sysUser);
RequestHolder.add(req);
filterChain.doFilter(servletRequest,servletResponse);
return;
}

@Override
public void destroy() {
}
}

2.3.1拦截器与过滤器的区别:

1、拦截器是基于Java反射机制的,而过滤器是基于函数回调的

2、拦截器不依赖于servlet容器, 依赖于web框架 , 过滤器依赖与servlet容器。

3、 拦截器只对action 起作用,而过滤器则可以对几乎所有的请求起作用,,并且可以对请求的资源进行起作用,但是缺点是一个过滤器实例只能在容器初始化时调用一次。

4、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

2.文件上传:

2.1:环境配置:

2.1.1:pom.xml文件配置:

1
2
3
4
5
6
7
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>


2.1.2:spring-servlet

3、ssM框架集成与测试

4、RestFull url

5、全局异常

springboot环境搭建:

配置父类

plant_do_care_info,plant_do_familia,plant_do_familia_genus,plant_do_genus,plant_do_info

Lombok 使用:

详解Lombok中的@Builder用法 - 简书 (jianshu.com)

1
2
@NoArgsConstructor  创建一个无参构造
@AllArgsConstructor创建有参

下面写这行配置是引入component的扫描组件

<context:component-scan base-package=”com.mmnc”>
其中base-package为指定需要扫描的包(含所有子包) ,扫描被@Service、@Controller、@Repository、@Component等注解标注的Java类,将其扫描注入到Spring容器,注入成Bean:@Service用于标注业务层组件
@Controller用于标注控制层组件(如struts中的action)
@Repository用于标注数据访问组件,即DAO组件.
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注,标识为一个Bean。

@Autowired和@Resource注解的区别和联系:

Spring注入中byType和byName的总结

1.首先,区分清楚什么是byType,什么是byName。

1
2
3
<bean id="userServiceImpl" class="cn.com.bochy.service.impl.UserServiceImpl" autowire="byName">
</bean>
<bean id="userDao" class="cn.com.bochy.dao.impl.UserDaoImpl"> </bean>

对于byName和byType方式不太熟悉的可以看一下这里:Spring中的byName与byType

简单来说,byName就是变量名去匹配bean的id属性,而byType则是变量类型去匹配bean的class属性

1
2
3
4
<bean id="userService" class="com.test.UserServiceImpl">
</bean>
@Autowired
private UserService userService;

此处byName就是拿变量名userService去匹配IOC容器的iduserService,匹配成功;而byType就是拿变量类型UserService去匹配IOC容器的idcom.test.UserService.UserServiceImpl,因为UserServiceImpl是UserService实现,所以也匹配成功

1、联系:

  1. @Autowired和@Resource注解都是作为bean对象注入的时候使用的
  2. 两者都可以声明在字段和setter方法上

2、区别:

@Autowired注解是Spring提供的,而@Resource注解是J2EE本身提供的
@Autowird注解默认通过byType方式注入,而@Resource注解默认通过byName方式注入
@Autowired注解注入的对象需要在IOC容器中存在,否则需要加上属性required=false,表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错

段代码,byName就是通过Bean的id或者name,byType就是按Bean的Class的类型

@Autowird默认的注入方式为byType,也就是根据类型匹配,当有多个实现时,则通过byName注入,也可以通过配合@Qualifier注解来显式指定name值,指明要使用哪个具体的实现类

1
2
3
4
5
6
7
// 方式一:改变变量名
@Autowired
private UserService userServiceImpl1;
// 方式二:配合@Qualifier注解来显式指定name值
@Autowired
@Qualifier(value = "userServiceImpl1")
private UserService userService;

总的来说,通过匹配映射进行查找,当 实现类有多个时候需要指定具体的name

@Resource注解的使用

步骤:@Resource默认通过byName注入,如果没有匹配则通过byType注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 1. 默认方式:byName
@Resource
private UserService userDao;

// 2. 指定byName
@Resource(name="userService")
private UserService userService;

// 3. 指定byType
@Resource(type=UserService.class)
private UserService userService;

// 4. 指定byName和byType
@Resource(name="userService",type=UserService.class)
private UserService userService;

既没指定name属性,也没指定type属性:默认通过byName方式注入,如果byName匹配失败,则使用byType方式注入(也就是上面的那个例子)
指定name属性:通过byName方式注入,把变量名和IOC容器中的id去匹配,匹配失败则报错
指定type属性:通过byType方式注入,在IOC容器中匹配对应的类型,如果匹配不到或者匹配到多个则报错
同时指定name属性和type属性:在IOC容器中匹配,名字和类型同时匹配则成功,否则失败

Springboot 配置文件:

Spring Boot默认会读取全局配置文件,配置文件名固定为: application.properties 或 appLication.ymL#放置在 src/main/resources资源目录下,使用配置文件米修改 SpringBoot自动配置的默认位。

1
2
3
server:
# 端口
port: 8081

1.K:v表示键值对关系,宫号后面必须有一个空格

2,使用空格的缩进表示层级关系,空格数目不重要,只要是左对齐的一列数据,都是同一个层级的兹

3.大小写敏感

4.缩进时不允许使用Tab键,只允许使用空格。

start坐标&自动化配置:

​ web start坐标

1
2
3
4
5
    <!--web 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependenc

image-20211115161548764

这里引入的web环境坐标不像传统的maven坐标那样包含坐标的版本号,项目中引入的 starter系列坐标对应的版本库统一由父工程坐标统一控制即项目中引入的parent标签。

image-20211125103847486

@AutoConfigurationPackage 底层是一个@import(AutoConfigurationImportSelecttor.Register.class) ,其会把启动类的包都扫进Spring的容器中 ,自动配置类

image-20211125103940684

image-20211125105852343

springboot通过 maven 中的starter 导入了所需场景下的jar包,并通过启动类上的@springBootApplication中的@EnableAutoConfiguration读取了类路径下的META-INF、spring.factories下 EnableAutoConfiguration 的配置类,这些配置类使用 @ConditionalOnnClass 来进行自动化环境的配置

Profile配置

Profile 是 Spring 用来针对不同环境