spring:详解控制反转IOC和AOP

news/2024/7/5 3:48:40

文章目录

    • IOC
      • 工厂模式
      • 实例
      • 基于xml管理Bean
      • 基于注解管理Bean
        • 常用注解:用于创建对象的
        • 常用注解:用于注入数据的
        • 常用注解:和生命周期相关的(了解)
        • 常用注解:新注解

IOC

IOC (Inversion of Control)是Spring的核心概念之一。它是指控制反转,它改变了程序员的编程习惯,将应用程序的控制权从应用程序代码中转移到IoC容器中,使应用程序变得更加灵活和易于维护。Spring中的IoC容器充当了控制权的中心,通过配置文件或注解,容器将对象实例化、组装和配置,然后将它们提供给应用程序代码使用。

DI:Dependency Injection,中文意思是依赖注入。依赖注入(DI)是实现控制反转的一种方式,它通过容器自动将所需的依赖关系注入到对象中,从而实现对象之间的解耦。在Spring中,依赖注入可以通过XML配置文件或注解方式来实现。

关于XML方式和注解的方式创建和使用java bean,我们一般使用注解的方式,java bean 可以理解为 js 中的对象,类似这样:

package cn.itcast.domain;

public class User {
    private int id;
    private String name;
    private int age;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

作用:解耦

我结合我常用 js 的方式说一下我理解的IOC,在 js 中我们习惯用函数式编程来解耦我们的程序,函数式其实就是让依赖由函数传入,而不是在函数内部获取。其实和IOC一样,IOC也是让依赖从外部获取,这里的注入的依赖 userService
@Autowired
private UserService userService;
其实就是js函数里的形参 function (userService) {}。

工厂模式

本来我们直接用 new 的方式会让 app 和资源是直接依赖的无法消除,而使用 ioc 我们让 app 问工厂要资源,工厂去控制资源的调度。这种控制权发生的转移我们就叫控制反转。
在这里插入图片描述

实例

例如,假设我们有一个名为UserService的类,它需要与数据访问对象(DAO)进行交互。如果我们将UserService与DAO紧密耦合在一起,那么每次需要修改数据访问的实现时,就需要修改UserService的实现。而如果我们使用控制反转,则可以将DAO的实现作为一个bean注入到UserService中,这样UserService只需要关注其需要的数据访问操作,而不需要关注具体的DAO实现。

@Service  
public class UserService {  
  
    @Autowired  
    private UserDao userDao;  
  
    public List<User> getAllUsers() {  
        return userDao.getAll();  
    }  
  
    public User getUserById(int id) {  
        return userDao.getUserById(id);  
    }  
  
    // Other methods...  
}

在上述代码中,UserService类通过@Autowired注解将UserDao类的实例注入到自身中,从而避免了直接在UserService类中创建UserDao实例。这是控制反转的一个基本例子,它通过将对象的创建和管理交给了Spring容器来降低类之间的耦合度。

基于xml管理Bean

一般很少用

基于注解管理Bean

注解的概念:和XML文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。

但是追根本源:所有一切的操作都是由Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行。

常用注解:用于创建对象的

使用@Component注解标记普通组件(相当于在 xml 中配置一个 bean,属性
value:指定 bean 的 id。如果不指定 value 属性,默认 bean 的 id 是当前类的类名。首字母小写。)

import org.springframework.stereotype.Component;

@Component
public class CommonComponent {
}

使用@Repository注解标记持久化层组件

import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements UserDao {

}

使用@Service注解标记业务逻辑组件

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
}

使用@Controller注解标记控制层组件

import org.springframework.stereotype.Controller;@Controller
public class UserController {
}

我们可以点进去查看源码,我们会发现:@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。对于Spring的IOC容器来说,这三个组件本质上没有什么区别,而他们的的作用主要是来提高代码的可读性。

常用注解:用于注入数据的

@Autowired、@Qualifier、@Resource和@Value是Spring框架中常见的注解,它们的区别主要有以下几点:

@Autowired和@Qualifier:这两个注解都是Spring的注解,用于自动装配bean。@Autowired用于自动装配bean,@Qualifier用于指定在存在多个相同类型的bean时,注入哪一个bean。
@Resource:这个注解属于J2EE的注解,用于自动装配bean。默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。使用这个注解,需要在J2EE环境中才能使用。
@Value:这个注解是Spring框架的注解,用于注入基本类型和String类型的值。这个注解有一个value属性,用于指定数据的值。可以使用Spring中的SpEL(也就是Spring的EL表达式)来定义复杂的表达式。这个注解不能用于装配bean,只能用于注入值。
总结起来,这四个注解的作用各不相同,@Autowired和@Qualifier主要用于自动装配bean,@Resource主要用于在J2EE环境中自动装配bean,而@Value主要用于注入基本类型和String类型的值。

在成员变量上使用@Autowired注解来完成自动装配
在controller层装配Service

@Controller
public class UserController {

    @Autowired
    private UserService userService;
    public void add(){
        userService.add();
    }
}

在这个例子中,我们有两个同类型的SomeService bean,通过@Qualifier注解指定我们想要注入的bean的名称。

@Configuration  
public class AppConfig {  
  
    @Bean  
    @Qualifier("someService1")  
    public SomeService someService1() {  
        return new SomeService();  
    }  
  
    @Bean  
    @Qualifier("someService2")  
    public SomeService someService2() {  
        return new SomeService();  
    }  
  
    @Autowired  
    @Qualifier("someService2")  
    private SomeService someService;  
}
常用注解:和生命周期相关的(了解)

@PostConstruct:用于指定初始化方法。
@PreDestroy:用于指定销毁方法。

常用注解:新注解

@ComponentScan
用于指定 spring 在初始化容器时要扫描的包。作用和在 spring 的 xml 配置文件中的:
<context:component-scan base-package="com.itheima"/> 是一样的。

@Configuration
@ComponentScan("com.itheima")
public class SpringConfiguration {
}

我们已经配置好了要扫描的包,但是数据源和 JdbcTemplate 对象如何从配置文件中移除呢?

@Bean:
该注解只能写在方法上,表明使用此方法创建一个对象,并且放入 spring 容器。

@PropertySource:
用 于 加载 .properties 文件 中的 配置 。 例如 我们 配置 数据 源时 , 可以 把连 接数 据库 的信 息 写 到
properties 配置文件中,就可以使用此注解指定 properties 配置文件的位置。
属性:
value[]:用于指定 properties 文件位置。如果是在类路径下,需要写上 classpath:

public class JdbcConfig {
	@Value("${jdbc.driver}")
	private String driver;
	@Value("${jdbc.url}")
	private String url;
	@Value("${jdbc.username}")
	private String username;
	@Value("${jdbc.password}")
	private String password;
	/**
	* 创建一个数据源,并存入 spring 容器中
	* @return
	*/
	@Bean(name="dataSource")
	public DataSource createDataSource() {}
}
jdbc.properties 文件:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/day44_ee247_spring

http://lihuaxi.xjx100.cn/news/1605112.html

相关文章

离散傅里叶变换(DFT)的推导及C语言实现

1、傅里叶变换&#xff08;FT&#xff09; 傅里叶变换&#xff08;连续时间傅里叶变换&#xff09;是该部分内容的理论基础&#xff0c;回顾一下&#xff1a; 傅里叶变换&#xff1a; 傅里叶逆变换&#xff1a; 以上是连续时间傅里叶变换&#xff0c;但计算机只能处理离散的数…

ssm+vue的车辆出租管理系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的车辆出租管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

基于SpringBoot的音乐网站

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 歌曲分类管理 歌曲信息管理 轮播图管理 歌曲信息 歌曲评论 用户注册 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施…

windows桌面程序与服务程序通过公共文件目录交互

windows权限管理越来越严格&#xff0c;桌面应用和服务之间的交互就很成问题。服务通常以独立的服务身份运行&#xff0c;而且在用户登录之前就开始运行&#xff0c;显然不能去访问用户私人的数据&#xff0c;况且既然是服务&#xff0c;同时为多个不同的登录用户服务也是很常见…

mysql双主主键冲突

在MySQL中&#xff0c;当使用双主键&#xff08;也称为复合主键&#xff09;时&#xff0c;可能会遇到主键冲突的问题。主键冲突通常发生在以下情况&#xff1a; 插入冲突&#xff1a;当尝试插入一行数据时&#xff0c;该行的复合主键已经存在于表中时&#xff0c;就会发生主键…

记录宝塔面板申请ssl证书报错 Invalid version. The only valid version for X509Req is 0

问题 宝塔面板申请ssl证书报错 Invalid version. The only valid version for X509Req is 0。 原因是由于服务器端使用了不兼容的 OpenSSL 版本导致的&#xff0c;服务器端的X509Req 版本只支持 0&#xff0c;而宝塔这边默认的版本为2。 我的是之前可以申请ssl&#xff0c;过…

面试算法25:链表中的数字相加

题目 给定两个表示非负整数的单向链表&#xff0c;请问如何实现这两个整数的相加并且把它们的和仍然用单向链表表示&#xff1f;链表中的每个节点表示整数十进制的一位&#xff0c;并且头节点对应整数的最高位数而尾节点对应整数的个位数。例如&#xff0c;两个分别表示整数98…

RPA技术如何重塑制造业的未来

根据Statista的预测&#xff0c;2023年RPA技术的全球市场规模预计将达到100亿美元&#xff0c;制造业将在实现这一目标方面发挥重要作用。这个蓬勃发展的行业面临着对不同重复过程的更多依赖&#xff0c;因此选择了数字化转型&#xff0c;制造业中的RPA有助于实现自动化和优化核…