0%

Spring学习

1. 什么是Spring

一个轻量级的控制反转(IOC)和面向切面(AOP)的框架

  • 一个开源的免费框架(容器)
  • 轻量级、非入侵式的框架
  • 控制反转(IOC)和面向切面编程(AOP)
  • 支持对事务的处理、对框架整合的支持

2. spring的组成

image-20230703141900747

主要有七大模块组成,基本上是一个大杂烩,各种东西的整合,核心是 Spring core

3. Spring拓展

  • Spring boot:构建一切
    • 约定大于配置
    • 简单配置便可以搭建起一个微服务
  • Spring Cloud:协调一切
  • Spring Cloud Data Flow:连接一切

由于Spring不断发展,整合的框架越来越多,导致冗杂,配置地狱,使用Spring Boot解决这个问题,因此学习Spring boot前先学习Spring和Spring MVC作为基础

4. IOC创建对象的方式

  • 无参构造构建对象,默认方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class User {
String name;

public User(){
//new User这个对象时便默认使用这个无参构造方法
System.out.println("User的无参构造");
}

public String getName() {
return name;
}

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

public void show(){
System.out.println("name=" + name);
}
}

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<bean id="user" class="com.pojo.User">
<property name="name" value="ajnuy"/>
</bean>

</beans>
1
2
3
4
5
6
7
8
9
public class MyTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

User user = (User) applicationContext.getBean("user");
user.show();

}
}
  • 有参构造构建对象

    1.下标赋值

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
public class User {
String name;

// 第一种方式,使用默认的无参构造
// public User(){
// System.out.println("User的无参构造");
// }

// 第二种方式,使用构造器构造
public User(String name){
this.name = name;
}

public String getName() {
return name;
}

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

public void show(){
System.out.println("name=" + name);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<!-- 第一种方式,使用默认参数构造-->
<!-- <bean id="user" class="com.pojo.User">-->
<!-- <property name="name" value="ajnuy"/>-->
<!-- </bean>-->

<!-- 第二种方式,有参构造-->
<!-- 1,使用下标-->
<bean id="user" class="com.pojo.User">
<constructor-arg index="0" value="ajnuy构造器构造"/>
</bean>


</beans>

​ 2.通过类型进行创建,有可能多个参数是同一种类型,不推荐使用

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
public class User {
String name;

// 第一种方式,使用默认的无参构造
// public User(){
// System.out.println("User的无参构造");
// }

// 第二种方式,使用构造器构造
public User(String name){
this.name = name;
}

public String getName() {
return name;
}

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

public void show(){
System.out.println("name=" + name);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<!-- 第一种方式,使用默认参数构造-->
<!-- <bean id="user" class="com.pojo.User">-->
<!-- <property name="name" value="ajnuy"/>-->
<!-- </bean>-->

<!-- 第二种方式,使用构造器构造-->
<!-- 1,使用下标-->
<!-- <bean id="user" class="com.pojo.User">-->
<!-- <constructor-arg index="0" value="ajnuy构造器构造"/>-->
<!-- </bean>-->
<!-- 2,使用参数类型-->
<bean id="user" class="com.pojo.User">
<constructor-arg type="java.lang.String" value="ajnuy构造器构造,使用参数类型"/>
</bean>


</beans>

​ 3.使用参数的名称构造在,重点掌握

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
public class User {
String name;

// 第一种方式,使用默认的无参构造
// public User(){
// System.out.println("User的无参构造");
// }

// 第二种方式,使用构造器构造
public User(String name){
this.name = name;
}

public String getName() {
return name;
}

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

public void show(){
System.out.println("name=" + name);
}
}
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
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<!-- 第一种方式,使用默认参数构造-->
<!-- <bean id="user" class="com.pojo.User">-->
<!-- <property name="name" value="ajnuy"/>-->
<!-- </bean>-->

<!-- 第二种方式,使用构造器构造-->
<!-- 1,使用下标-->
<!-- <bean id="user" class="com.pojo.User">-->
<!-- <constructor-arg index="0" value="ajnuy构造器构造"/>-->
<!-- </bean>-->
<!-- 2,使用参数类型-->
<!-- <bean id="user" class="com.pojo.User">-->
<!-- <constructor-arg type="java.lang.String" value="ajnuy构造器构造,使用参数类型"/>-->
<!-- </bean>-->
<!-- 3,使用参数的名称构造-->
<bean id="user" class="com.pojo.User">
<!-- 注意,这里和无参构造是不同的,一个是用的构造器构造(有参),另一个使用的是默认的property标签进行构造-->
<constructor-arg name="name" value="ajnuy,使用属性的名称构造"/>
</bean>

</beans>

总结,所有放在bean容器中管理的对象,在一开始加载的时候便已经被new出来了

1
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");

也就是这个时候

5. spring配置

1. 别名

1
2
<!--    给用户创建一个别名,可以使用别名来创建对象-->
<alias name="user" alias="userNickName"/>

2. bean的配置

1
2
3
4
5
6
7
8
<!--
id:对象初始化创建后的具体名称
class:对象对应的具体的类的地址
name:可以为每个初始化的对象取多个别名
-->
<bean id="user" class="com.pojo.User" name="user2 u2 u">
<constructor-arg name="name" value="bean构造测试"/>
</bean>

3. import导入

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
</beans>

在团队开放中,可以将不同成员写的bean配置文件合并为一个

6. 依赖注入

1. 构造器注入(前面所讲的构造器)

2. set注入(重点)

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

【环境搭建】

1.复杂类型

2.真实测试对象

八种真实的注入类型

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
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<bean id="address" class="com.pojo.Address"/>

<bean id="student" class="com.pojo.Student">
<!-- 第一种,普通值的注入,value-->
<property name="name" value="ajnuy"/>

<!-- 第二种,对象的注入,ref-->
<property name="address" ref="address"/>

<!-- 第三种,数组的注入,array-->
<property name="books">
<array>
<value>三体</value>
<value>哈利波特</value>
<value>三国演义</value>
<value>水浒传</value>
</array>
</property>

<!-- 第四种,列表的注入,list-->
<property name="hobbies">
<list>
<value></value>
<value></value>
<value>rap</value>
<value>篮球</value>
</list>
</property>

<!-- 第五种,map的注入,map-->
<property name="card">
<map>
<entry key="身份证" value="111111222223631411"/>
<entry key="银行卡" value="1468464131314861321"/>
</map>
</property>

<!-- 第六种,set的注入,set-->
<property name="games">
<set>
<value>PUBG</value>
<value>BF</value>
<value>COD</value>
<value>APEX</value>
</set>
</property>

<!-- 第七种,null的注入,null-->
<property name="wife">
<null/>
</property>

<!-- 第八种,property的注入,props-->
<property name="info">
<props>
<prop key="driver">3231</prop>
<prop key="url">www.da.com</prop>
<prop key="user">root</prop>
<prop key="password">root</prop>
</props>
</property>
</bean>

</beans>

3. p命名空间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- <bean id="user" class="com.pojo.User">-->
<!-- <property name="name" value="ajnuy"/>-->
<!-- <property name="age" value="20"/>-->
<!-- </bean>-->

<!-- 与上述写法相同,简化写法-->

<bean id="user" class="com.pojo.User" p:name="ajnuy" p:age="20"/>


</beans>

重点要引入xml的约束

1
xmlns:p="http://www.springframework.org/schema/p"

4. c命名空间

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
<?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:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<!-- <bean id="user" class="com.pojo.User">-->
<!-- <property name="name" value="ajnuy"/>-->
<!-- <property name="age" value="20"/>-->
<!-- </bean>-->

<!-- 与上述写法相同,简化写法-->

<bean id="user" class="com.pojo.User" p:name="ajnuy" p:age="20"/>

<!-- <bean id="user2" class="com.pojo.User">-->
<!-- <constructor-arg name="name" value="ajnuy"/>-->
<!-- <constructor-arg name="age" value="23"/>-->
<!-- </bean>-->

<!-- 与上述写法相同,简化写法-->
<bean id="user2" class="com.pojo.User" c:name="AJNUY" c:age="20"/>

</beans>

重点还是引入约束

1
xmlns:c="http://www.springframework.org/schema/c"

7. bean的作用域(scope)

1. 单例模式(默认机制)

1
<bean id="user2" class="com.pojo.User" c:name="AJNUY" c:age="20" scope="singleton"/>

所有getBean()拿到的对象是同一个对象

2. 原型对象

1
<bean id="user2" class="com.pojo.User" c:name="AJNUY" c:age="20" scope="prototype"/>

每次通过getBean()拿到的对象都是不同的

3. 其他

request, session, application,均用于web开发中

8. bean的自动装配(autowire)

  • spring可以使用自动装配来满足bean的依赖要求
  • spring会在上下文中自动寻找,并且自动地给bean配置属性

1. spring的三种装配方式

  • xml中显式配置(一般常用)
  • java中显式配置
  • 隐式的自动配置bean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<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.xsd">

<bean id="cat" class="com.pojo.Cat"/>
<bean id="dog" class="com.pojo.Dog"/>

<!--
byName:会在容器的上下文中(此处为people容器)寻找,和自己的属性名称相同的bean(people的两个属性为cat和dog,因此会装配id为cat和dog的两个bean),
实现自动装配
byType:会在容器的上下文中(此处为people容器)寻找,和自己的属性名称相同的bean(people的两个属性类型为Cat和Dog,因此会装配class为Cat和Dog的两个bean),
实现自动装配
-->

<bean id="people" class="com.pojo.People" autowire="byType">
<property name="name" value="ajnuy"/>
</bean>

</beans>

注意:使用byName时要保证所有的bean的id唯一,且id要和对应的属性名称一致;使用byType时要保证所有bean的class唯一,且class要和对应的属性类型一致

2. 使用注解自动装配

使用注解的要求:

  1. 导入约束:context约束
  2. 配置依赖
1
2
3
4
5
6
7
8
9
10
11
12
<?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">

<context:annotation-config/>

</beans>
1. @Autowired

可以直接在属性上使用,亦可以在set方法上使用

使用@Autowired后可以不用写set方法了,但是该属性应该已经提前在容器中存在了,且要符合名字

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
package com.pojo;

import org.springframework.beans.factory.annotation.Autowired;

public class People {
private String name;
@Autowired
private Cat cat;
@Autowired
private Dog dog;

public String getName() {
return name;
}

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

public Cat getCat() {
return cat;
}

// @Autowired
public void setCat(Cat cat) {
this.cat = cat;
}

// @Autowired
public Dog getDog() {
return dog;
}

public void setDog(Dog dog) {
this.dog = dog;
}

@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", cat=" + cat +
", dog=" + dog +
'}';
}
}

如果装配的环境比较复杂,使用单一的@Autowired无法完成时,可以使用@Qualifier(value=”某个bean的id”)进行配置,以指定一个唯一的bean容器

补充:@Nullable:打上该注解,表明该字段可以为空

9. 使用注解开发

1. @Autowired和@Qualifier(value=”xxx”)

上面已经详细讲述,此处不多赘述

2. @Nullable

表示某个字段可以为空

3. @Component

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

//相当于<bean id="user" class="com.pojo.User"/>
@Component
public class User {
private String name;

public String getName() {
return name;
}

// 等价于<property name="name" value="ajnuy"/>
@Value("ajnuy")
public void setName(String name) {
this.name = name;
}
}

一般使用在具体的实体类中,加上该注解会让spring进行自动装载到容器中

但是要提前在xml文件中加上

1
2
<!--    自动扫描指定包,查看是否存在组件,若是存在,便加入bean进行管理-->
<context:component-scan base-package="com.pojo"/>

@Component的几个衍生注解:采用MVC三层架构

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

四个注解(加上@Component)的功能是一样的,都是将某个类注册到spring中,并进行装配

4. @singleton(“xxx”)

相当于scope=”singleton”

--------------本文结束感谢您的阅读--------------