spring框架-IOC注入

Spring框架

1.是什么:

它是一个容器,是整合其他框架的框架,它的核心是IOC和AOP,它由20个模块构成,在很多领域都提供优秀的解决方案

2.特性:

轻量级

由20多个模块构成,每个jar包都很小,小于1M,核心包也就3M左右

AOP(面向切面编程)

将公共的,通用的,重复的代码单独开发,在需要的时候反织回去,底层的原理是动态代理(例如持久层,业务逻辑层,view层都需要输出打印日志,日志就可以做成公共的,需要的时候调用)

IOC (控制反转)

由spring容器进行对象的创建和依赖的注入,程序员在使用时直接取出来使用

正转:由程序员进行对象的创建和依赖注入

Student stu = new Student(); 程序员创建对象

stu.setName(“张三”); 程序员进行赋值

stu.setAge(22);

反转:由Spring容器创建对象和依赖注入称为反转

– Spring容器负责对象的创建

–spring容器依赖注入值

备注:切记spring容器在启动时,就创建所有的对象stu。。。

代码无污染

没有约束,例如maven有规定的目录约束

3.相关用法:

————————————基于xml的IOC————————————

  • 1)创建对象

resource目录下创建命名为applicationContext.xml的文件,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class MyTest1{
@Test
public void testStudent(){
//程序员创建对象
Student stu = new Student();
System.out.println(stu);
}

@Test
public void testStudentSpring(){
//有spring容器进行对象的创建
//如果想从spring容器中取出对象,则要先创建容器对象,并启动才可以取对象
//s01/applicationContext.xml,这里可以在resource目录下再建一个s01文件夹
ApplicationCOntext ac = new ClassPathXmlApplicationContext("s01/applicationContext.xml")
//取出对象
Student stu = (Student) ac.getBean("stu");
}

}
  • 2)给创建的对象赋值

​ A 使用setter注入

​ 简单类型注入值使用value属性

​ 引用类型注入值使用ref属性

​ ⚠️注意:使用setter注入必须提供无参的构造方法,必须提供setXXX()方法。

1
2
3
4
5
6
7
8
9
10
11
# 创建学校对象
<bean id="school" class="com.yuting.School"> -- Spring容器负责对象的创建
<property name="name" value="清华大学"> --spring容器依赖注入值
<property name="address" value="海淀区">
</bean>

<bean id="stu" class="com.yuting.Student">
<property name="name" value="张三">
<property name="age" value="22">
<property name="sch" ref="school">
</bean>

​ B 使用构造方法注入

​ a.使用构造方法的参数名称进行注入值

​ b.使用构造方法参数的下标注入值

​ 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
## 使用构造方法的参数名称进行注入值
public class School{
private String name;
private String address;
public School(String name1,String address1){
this.name = name1;
this.address = address1;
}
}

<bean id="school" class="com.yuting.School"> -- Spring容器负责对象的创建
<constructor-arg name="name1" value="清华大学"></constructor-arg>
<constructor-arg name="address1" value="海淀区"></constructor-arg>
</bean>


## 使用构造方法参数的下标注入值
public class Student{
private String name;
private int age;
private School school;

public Student(String name,int age, School school){
this.name = name;
this.age = age;
this.school = school;
}
}

<bean id="stu" class="com.yuting.Student"> -- Spring容器负责对象的创建
<constructor-arg index="0" value="ywq"></constructor-arg>
<constructor-arg index="1" value="20"></constructor-arg>
<constructor-arg index="2" ref="school"></constructor-arg>
</bean>


## 使用默认的构造方法的参数的顺序注入值
<bean id="stuSequence" class="com.yuting.Student"> -- Spring容器负责对象的创建
<constructor-arg value="yt"></constructor-arg>
<constructor-arg value="20"></constructor-arg>
<constructor-arg ref="school"></constructor-arg>
</bean>

————————————基于注解的IOC————————————

也称为DI(Dependency Injection),它是IOC的具体实现的技术

汤:xml annotation

药:创建对象并依赖注入

  • 1)创建对象的注解

​ @Component:可以创建任意对象,创建对象的默认名称是类名的驼峰命名法。也可以指定对象的名称。

​ @Controller:专门来创建控制器的对象(Servlet), 这种对象可以接收用户的请求,可以返回处理结果给客户端

​ @Service:专门用来创建业务逻辑层的对象,负责向下访问数据访问层,处理完毕后的结果返回给界面层。

​ @Repository:专门用来创建数据访问层的对象,负责数据库中的增删改查所有操作

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
@Component
public class Student{
private String name;
private int age;

public Student(){
System.out.println("学生对象的无参构造方法")
}
}

@Component("stu")
public class Student{
private String name;
private int age;

public Student(){
System.out.println("学生对象的无参构造方法")
}
}

# applicationContext.xml
<!--添加包扫描-->
# 只要包下面有顶着那些创建对象的注解,就给你自动创建对象
<context:component-scan base-package="com.yuting.s01"></context:component-scan>


@Test
public void testStudentSpring(){
//有spring容器进行对象的创建
//如果想从spring容器中取出对象,则要先创建容器对象,并启动才可以取对象
//s01/applicationContext.xml,这里可以在resource目录下再建一个s01文件夹
ApplicationCOntext ac = new ClassPathXmlApplicationContext("s01/applicationContext.xml")
//取出对象
Student stu = (Student) ac.getBean("stu");
}
}
  • 2)创建依赖的注解

    值类型的注入

​ @value:用来给简单类型注入值

1
2
3
4
5
6
7
8
9
10
11
12
@Component("stu")
public class Student{
@Value("zhangsan")
private String name;
@Value("22")
private int age;

public Student(){
System.out.println("学生对象的无参构造方法")
}
}

引用类型的注入

​ A.@Autowired:使用类型注入值,从整个Bean工厂中搜索同源类型的对象进行注入

​ 同源类型:

​ 1.被注入的类型(Student中的school)与注入的类型是完全相同的类型

​ 2.被注入的类型(Student中的school父)与注入的类型(子)是父子类

​ 3.被注入的类型(Student中的school接口)与注入的类型(实现类)是接口和实现类的类型

注:在有父子类的情况下,使用按类型注入,就意味着有多个可注入的对象,此时按照名称进行二次筛选,选中与被注入对象相同名称的对象进行注入

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
-------------1.被注入的类型(Student中的school)与注入的类型是完全相同的类型-----------
@Component
public class School{
@Value("清华大学")
private String name;
@Value("海淀区")
private String address;

public School(){
System.out.println("school对象的无参构造方法")
}
}

@Component
public class Student{
@Value("lisi")
private String name;
@Value("23")
private int age;

//引用类型按类型注入
@Autowired
private School school;
}

# applicationContext.xml
<!--添加包扫描-->
# 只要包下面有顶着那些创建对象的注解,就给你自动创建对象
<context:component-scan base-package="com.yuting.s01"></context:component-scan>


-------------------2.被注入的类型(Student中的school父)与注入的类型(子)是父子类--------------------
@Component("schoolNew")
public class School{
@Value("清华大学")
private String name;
@Value("海淀区")
private String address;

public School(){
System.out.println("school对象的无参构造方法")
}
}

@Component("school")
public class SubSchool extends School{
@Value("清华附小")
private String name;
@Value("海淀小区")
private String address;

public SubSchool(){
System.out.println("这是SubSchool的构造方法")
}
}

@Component
public class Student{
@Value("lisi")
private String name;
@Value("23")
private int age;

//引用类型按类型注入
@Autowired
private School school;
}

默认:父类被注入进来
结果:子类被注入进来

--3.被注入的类型(Student中的school接口)与注入的类型(实现类)是接口和实现类的类型

​ B.@Autowired

​ @Qualifier:使用名称注入值,从整个Bean工厂中搜索相同名称的对象进行注入

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
@Component //交给spring去创建对象
public class School{ //此时School对象的名称就是school
@Value("清华大学")
private String name;
@Value("海淀区")
private String address;

public School(){
System.out.println("school对象的无参构造方法")
}
}

@Component
public class Student{
@Value("lisi")
private String name;
@Value("23")
private int age;

//引用类型按名称注入
@Autowired
@Qualifier("school")// 按照名称school找
private School s;
}

# applicationContext.xml
<!--添加包扫描-->
# 只要包下面有顶着那些创建对象的注解,就给你自动创建对象
<context:component-scan base-package="com.yuting.s01"></context:component-scan>



创建spring项目

项目结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
__springDemo
____src
_______main
_________java
____________com
______________yuting
_________resources
____________applicationContext.xml
_______test
_________java
___________com
_____________yuting
_________resources
____pom.xml

1.新建maven项目

2.maven是代码污染框架,所以得按照maven规定的目录来

3.新建的文件夹要退出去才能被maven识别

4.修改pom文件

  • 添加依赖
  • build 增加配置文件路径(xml,properties等配置文件不需要编译,因此编译好的class文件会在target文件夹下找到配置文件,因为idea的原因,有些时候不会把配置文件copy到target目录下就没办法正常运行,所以build标签在编译时执行在编译阶段copy到target目录下)

5.resource目录下创建命名为applicationContext.xml的文件

三层架构的项目实例

界面层、业务逻辑层、数据访问层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
src.main.java.com.yuting.pojo     # 实体类
Users.java

src.main.java.com.yuting.dao # 数据访问层
UserMapper.java
UserMapperImpl.java

src.main.java.com.yuting.service # 业务逻辑层
impl
UserServiceImpl.java
UserService.java

src.main.java.com.yuting.controller # 界面层
UserController.java

Spring会接管三层架构中哪些对象的创建?

Users.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Users{
private int uid;
private String uname;
private int uage;

public int getUid(){return uid;};
public String getUname(){return uname;};
public int getUage(){return uage;};

public void setUid(int uid){this.uid=uid};
public void setUname(String uname){this.uname=uname};
public void setUage(int uage){this.uage=uage};

public Users(int uid,String uname,int uage){
this.uid=uid;
this.uname=uname;
this.uage=uage;
}
}

UserMapperImpl.java

1
2
3
4
5
6
@Repository // 交给spring框架去创建数据访问层的对象创建
public class UserMapperImpl implements UserMapper{
public int insert(Users u){
System.out.println(u.getUname()+'用户增加成功!');
}
}

UserMapper.java

1
2
3
public interface UserMapper{
int insert(Users u);
}

UserServiceImpl.java

1
2
3
4
5
6
7
8
9
10
11
@Service //交给spring框架创建业务逻辑层的对象
public class UserServiceImpl implements UsersService{
//在所有的业务逻辑中都必定有数据访问层的对象
@Autowired
private UsersMapper usersMapper; // = new UsersMapperImpl();

@Override
public int insert(Users users){
return usersMapper.insert(users)
}
}

UserService.java

1
2
3
4
5
public interface UsersService{
//在所有的业务逻辑中都必定有数据访问层的对象

int insert(Users users);
}

UserController.java

1
2
3
4
5
6
7
8
9
10
11
@Controller
public class UserController{
//所有的界面层都会有业务逻辑层的对象
@Autowired
public UsersService userService;// = new UsersServiceImpl();

//界面层对外提供访问的功能
public int insert(Users users){
return userService.insert(users);
}
}

测试类.java

1
2
3
4
5
6
7
8
public class MyTest{
@Test
public void testInsertUsers(){
ApplicationContext ac = new ClassPathXmlApplicationCOntext("applicationContext.xml");
UserController userController = (UserController)ac.getBean("userController");
userController.insert(new Users(100,"haha",25));
}
}

觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭



wechat pay



alipay

spring框架-IOC注入
http://yuting0907.github.io/2022/09/15/spring框架-IOC注入/
作者
Echo Yu
发布于
2022年9月15日
许可协议