hincky的主页 hincky的主页
  • 学习笔记

    • Vue笔记
    • Vuepress
    • nginx
  • 语言类

    • java
    • go
    • python
    • 设计模式
  • 框架类

    • Spring
    • Spring Security
    • Mybatis
  • 容器技术

    • docker
    • k8s
    • helm
    • prometheus
    • grafana
    • jenkins
  • 命令集合

    • linux命令
    • docker命令
    • git命令
    • vim命令
    • k8s命令
  • 数据库

    • sql
    • mysql
  • 协议

    • 网络模型
    • http/1.1
    • WebSocket
    • http/2
    • TLS/SSL
    • tcp
    • IP
    • tcpdump抓包命令
    • wireshark抓包工具
  • 通用

    • Git
  • 技术分享

    • git push/pull总是超时怎么办
    • idea debug技巧
    • postman使用
    • 问题总结
    • idea使用技巧
  • Oauth2

    • Oauth2原理
  • 项目列表

    • redis项目
    • 微服务项目
  • 分类
  • 标签
  • 归档
  • 随笔
GitHub (opens new window)

Hincky

当有趣的人,做想做的事
  • 学习笔记

    • Vue笔记
    • Vuepress
    • nginx
  • 语言类

    • java
    • go
    • python
    • 设计模式
  • 框架类

    • Spring
    • Spring Security
    • Mybatis
  • 容器技术

    • docker
    • k8s
    • helm
    • prometheus
    • grafana
    • jenkins
  • 命令集合

    • linux命令
    • docker命令
    • git命令
    • vim命令
    • k8s命令
  • 数据库

    • sql
    • mysql
  • 协议

    • 网络模型
    • http/1.1
    • WebSocket
    • http/2
    • TLS/SSL
    • tcp
    • IP
    • tcpdump抓包命令
    • wireshark抓包工具
  • 通用

    • Git
  • 技术分享

    • git push/pull总是超时怎么办
    • idea debug技巧
    • postman使用
    • 问题总结
    • idea使用技巧
  • Oauth2

    • Oauth2原理
  • 项目列表

    • redis项目
    • 微服务项目
  • 分类
  • 标签
  • 归档
  • 随笔
GitHub (opens new window)
  • java

  • python

  • Spring

    • IoC控制反转
      • 使用Spring IoC
        • pom文件引入Spring context依赖
        • 创建实体类DataConfig
        • 创建测试类Test
      • 基于XML配置
        • 创建xml配置文件
        • 读取xml文件中bean对象配置
      • 基于注解配置
        • 配置类
        • 创建配置类和bean的配置方法
        • 读取配置类中bean的配置方法
        • 扫描包+注解
        • component注解将bean加入IoC
        • 读取指定的包
        • bean对象之间调用
        • Autowired类型注入
        • Qualifier名字注入
      • 总结IoC
    • AOP面向切面编程
      • 创建业务接口
      • 创建业务的实现类
      • 创建切面对象
      • 使用AOP
        • XML使用方式
        • 设置AOP代理
      • 总结
  • SpringMVC

  • SpringSecurity

  • Mybatis

  • 设计模式

  • Go

  • 后端
  • Spring
hincky
2022-10-31
目录

IoC控制反转

# IoC控制反转

在面向对象编程开发中,对象的创建和管理方式是实际开发中要面临的头部问题。Spring框架提供了IoC容器作为解决方案。

IoC是创建和管理对象的容器,因此你可以将IoC理解为Spring全家桶各个功能模块的基础。

IoC(控制反转),将对象的创建进行反转,常规情况下,对象都是开发者手动创建的

使用 IoC 开发者不再需要创建对象,而是由 IoC 容器根据需求自动创建项目所需要的对象。

  • 不用 IoC:所有对象开发者自己创建
  • 使用 IoC:对象不用开发者创建,而是交给 Spring 框架来完成

# 使用Spring IoC

用idea创建新的maven工程之后

# pom文件引入Spring context依赖

这一步是为了配置IoC的环境

Spring context(上下文)里面就包含了IoC的依赖了,除了IoC,还有aop,bean,context,core,expression,jcl依赖

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>5.3.15</version>
</dependency>
1
2
3
4
5

为了方便后面的开发,顺便引入lombok插件,来自动生成getter,setter方法,减少开发量。

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.22</version>
</dependency>
1
2
3
4
5

# 创建实体类DataConfig

package com.hincky.ioc;
import lombok.Data;

@Data
public class DataConfig {
    private String url;
    private String driverName;
    private String userName;
    private String password;
}
1
2
3
4
5
6
7
8
9
10

# 创建测试类Test

package com.hincky.ioc;
public class Test {
    public static void main(String[] args) {

      //不用IoC,就要像下面这样,所有对象的信息,都要自己固定的写死。
      //且对像数量多的话,又不方便又冗余
        DataConfig dc = new DataConfig();
        dc.setDriverName("Driver");
        dc.setUrl("localhost:8080");
        dc.setUserName("root");
        dc.setPassword("root");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13

环境搭建好了之后,就可以开始正式使用IoC了

IoC有两种使用方式

  • 基于XML配置bean
  • 基于注解配置bean

# 基于XML配置

这种方式,现在看来十分麻烦,已经不多用了

IoC基于XML配置bean对象:

  1. 开发者把需要的对象在 XML 中进行配置
  2. Spring框架读取这个配置文件,根据配置文件的内容来创建对象

# 创建xml配置文件

resources文件夹下创建

<?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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

    <bean class="com.hincky.ioc.DataConfig" id="config">
        <property name="driverName" value="Driver"></property>
        <property name="url" value="localhost:8080"></property>
        <property name="userName" value="root"></property>
        <property name="password" value="root"></property>
    </bean>

</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 读取xml文件中bean对象配置

回到Test测试类中,注释掉原来手写的bean配置信息。 下面通过创建IoC容器读取xml文件中bean对象的配置

// DataConfig dc = new DataConfig();
// dc.setDriverName("Driver");
// dc.setUrl("localhost:8080");
// dc.setUserName("root");
// dc.setPassword("root");

ApplicationContext context = new ClassPathXmlApplicationContext("ioc.xml");
System.out.println(context.getBean("config"));

1
2
3
4
5
6
7
8
9

这种基于xml文件的配置方式,底层原理就是xml解析+反射

# 基于注解配置

基于注解配置对象bean中,有两种常用的配置方式:

  • 配置类
  • 扫描包+注解

# 配置类

原理和xml的方式类似,就是配置bean对象的形式变为了java类和方法,不是xml文件了

# 创建配置类和bean的配置方法

package com.hincky.ioc.config;
import com.hincky.ioc.DataConfig;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class DataConfigConfig {
//    @Bean(value = "config")
    @Bean
    public DataConfig dataConfig() {
        DataConfig dataConfig = new DataConfig();
        dataConfig.setDriverName("Driver");
        dataConfig.setUrl("localhost:8080");
        dataConfig.setUserName("root");
        dataConfig.setPassword("root");
        return dataConfig;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 读取配置类中bean的配置方法

回到Test测试类中,注释掉之前的代码。

下面通过创建IoC容器读取配置类中bean对象的配置方法。

当配置类很多时,逐个引入不方便;通过扫描包的方式,将特定包下所有的带有注解的配置类加入到IoC容器中

// 注解:配置类。直接读取指定配置类
ApplicationContext context = new AnnotationConfigApplicationContext(DataConfigConfig.class);
//扫描包名下带有Configuration注解的配置类
// ApplicationContext context = new AnnotationConfigApplicationContext("com.hincky.ioc.config");
System.out.println(context.getBean("dataConfig"));
1
2
3
4
5

# 扫描包+注解

这是最最最常用的方式了,不再需要依赖于 XML 或者配置类

而是创建目标类的时候添加@component注解加入到IoC容器

# component注解将bean加入IoC

回到一开始创建的实体类中,通过@Value配置bean的属性值

@Data
@Component
public class DataConfig {
    @Value("localhost:8080")
    private String url;
    @Value("Driver")
    private String driverName;
    @Value("root")
    private String userName;
    @Value("root")
    private String password;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 读取指定的包

ApplicationContext context = new AnnotationConfigApplicationContext("com.hincky.ioc");
System.out.println(context.getBean(DataConfig.class));
1
2

# bean对象之间调用

比如创建一个GlobalConfig对象,里面调用DataConfig

这就需要IoC在创建GlobalConfig的时候,将DataConfig注入进来。

# Autowired类型注入

实现方式:利用@Autowired注解进行自动装载,自动去IoC容器里面找被@Autowired修饰的bean类型

@Data
@Component
public class GlobalConfig {
    @Value("80")
    private String port;
    @Value("com.hincky")
    private String path;
    @Autowired  //自动去IoC容器里面找DataConfig的bean
    private DataConfig dataConfig;
}
1
2
3
4
5
6
7
8
9
10

Test类读取一下GlobalConfig验证是否注入成功

ApplicationContext context = new AnnotationConfigApplicationContext("com.hincky.ioc");
System.out.println(context.getBean(GlobalConfig.class));
1
2

# Qualifier名字注入

因为@Autowired注解是通过类型进行匹配的,如果要通过名字进行匹配,就要用@Autowired+@Qualifier注解

@Data
@Component
public class GlobalConfig {
    @Value("80")
    private String port;
    @Value("com.hincky")
    private String path;
    @Autowired
    @Qualifier("config")
    private DataConfig dataConfig;
}
1
2
3
4
5
6
7
8
9
10
11

同时,被调用对象类上@Component的名字也要一致

@Data
@Component("config")
public class DataConfig {
    @Value("localhost:8080")
    private String url;
    @Value("Driver")
    private String driverName;
    @Value("root")
    private String userName;
    @Value("root")
    private String password;
}
1
2
3
4
5
6
7
8
9
10
11
12

# 总结IoC

  1. xml方式:
  • 写xml配置类
  • 创建Ioc容器,使用ClassPathXmlApplicationContext
  • 读取bean对象
  1. 注解-配置类方式:
  • 创建bean的java配置类,并在类上加@Configuration注解
  • 配置类里创建方法,这个方法对应一个bean对象。所以要在方法上加@Bean注解
  • 创建IoC容器,使用AnnotationConfigApplicationContext
    • 可以直接指定某个配置类
    • 也可以指定某个包名,Ioc容器会去扫描带有@Configuration注解的配置类,并将其加入IoC容器中
  • 读取bean对象
    • 默认是读取配置类里面bean方法的方法名。
    • 如果要自定义名字,就要改方法上注解为@Bean(value="config")
    • 也可以通过方法.class去读取bean对象,比如上面就是context.getBean(Dataconfig.class)
  1. 注解-扫描包+注解方式:
  • 实体类上添加@Component注解,将其添加到IoC容器
  • 实体类里面通过@Value配置bean的属性值
  1. 对象之间的调用
  • 调用对象和被调用对象通过@Component注解,注入到IoC容器中
  • 被调用对象在调用对象的类里面,要用@Autowired注解进行自动装载
    • @Autowired 是通过类型进行注入的,所以被调用对象在调用对象的类里面取什么名字都无所谓
    • 如果需要通过名字去获取被调用对象,就用@Autowired+@Qualifier
      • @Qualifier设置的名字一定要和被调用对象类上@Component的名字一致,不然找不到bean
      • 因为IoC里面不知道会不会有同名的其它类型bean,为了不挖坑,还是用类型去获取bean
编辑 (opens new window)
#Spring
IO流-文件
AOP面向切面编程

← IO流-文件 AOP面向切面编程→

最近更新
01
人生前期重要的能力
05-17
02
防火墙命令
04-11
03
docker-compose部署mysql主从集群
03-22
更多文章>
Theme by Vdoing | Copyright © 2022-2023 Hincky | MIT License | 粤ICP备2022120427号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式