spring

IoC、DI和AOP思想

IoC控制反转思想,强调是程序中将创建bean(主动new 创建对象)的权利反转给第三方

DI依赖注入思想,强调的是bean之间的依赖关系

AOP面向切面思想,功能的横向抽取,主要的实现方式就是proxy

IoC解决了哪些问题

上图代码中,业务层内通过new BookDaoImpl实例化bookDao,由bookDao进行具体的数据操作,当需要将BookDaoImpl换成BookDaoImpl2时,就需要修改业务层的代码,代码的耦合性高,为了解决这个问题,引出了IoC思想,即:程序中将创建bean(主动new 创建对象)的权利反转给第三方(容器)

spring实现了这个第三方(容器),也被称为IoC容器,这个容器内部帮我们创建了对象,IoC容器创建的对象也被称为bean

IoC容器内将serice与dao建立关系就是DI

IoC使用

  • 管理什么?(Service与Dao)
  • 如何将被管理的对象告知IoC容器?(配置)
  • 被管理的对象交给IoC容器,如何获取到IoC容器?(接口
  • IoC容器得到后,如何从容器中获取bean?(接口方法)

首先是不使用IoC的代码案例:

java 复制代码
package org.example;

import org.example.dao.BookDao;
import org.example.service.BookService;
import org.example.service.impl.BookServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        BookService bookService = new BookServiceImpl();
        bookService.save();

    }
}

输出:
book service save ...
book dao save

IoC入门 - 基于XML的IoC

1.pom.xml中配置依赖

复制代码
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.1.12</version>
</dependency>

2.xml中配置bean

复制代码
applicationContext.xml
XML 复制代码
<?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">

<!--    id是bean的名字, class是实现类-->
    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl" />
</beans>

id是bean的名字, class是bean的实现类

3.使用bean

java 复制代码
package org.example;

import org.example.dao.BookDao;
import org.example.service.BookService;
import org.example.service.impl.BookServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        // 获取IcC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取bean
//        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
//        bookDao.save();
        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}

DI使用

  • 前提是基于IoC管理的bean
  • Service中使用new形式创建的Dao对象是否保留?(否)
  • Service中需要的Dao对象如何引入到Service中?(提供方法)
  • Service与Dao间的关系如何描述?(配置)

DI入门 - 基于XML的DI

setter方法注入

引用类型注入
复制代码
xml中 使用property标签 + name + ref
java 复制代码
package org.example.service.impl;

import org.example.dao.BookDao;
import org.example.service.BookService;

public class BookServiceImpl implements BookService {
    // 1.删除Service中使用new创建的Dao对象
//    private BookDao bookDao = new BookDaoImpl() ;
    private BookDao bookDao;

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    // 2.Service中提供set方法创建Dao, 这个set方法是IoC容器调用的,通过xml中配置内容将bookDao传入
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}
复制代码
applicationContext.xml
XML 复制代码
<?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">

<!--    id是bean的名字, class是实现类-->
    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl">
<!--        3.配置Service与Dao的关系-->
<!--        name 表示配置哪一个具体属性-->
<!--        ref 表示参照哪一个bean-->
        <property name="bookDao" ref="bookDao"/>
    </bean>
</beans>

值类型注入

xml中 使用property标签 + name + value

java 复制代码
package org.example.service.impl;

import org.example.dao.BookDao;
import org.example.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao;
    private int year;
    private String name;

    public void save() {
        System.out.println("book service save"+name+year);
        bookDao.save();
    }
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public void setName(String name) {
        this.name = name;
    }
}
java 复制代码
<?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="bookDao" class="org.example.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl" scope="prototype">
<!--        引用类型注入-->
        <property name="bookDao" ref="bookDao"/>
<!--        值类型注入-->
        <property name="year" value="2024"/>
        <property name="name" value="《java入门》"/>
    </bean>
</beans>

构造器注入

引用类型注入
复制代码
xml中 使用constructor-arg标签 + name + ref  name可以换成type或index
java 复制代码
package org.example.service.impl;

import org.example.dao.BookDao;
import org.example.service.BookService;

public class BookServiceImpl implements BookService {
    private BookDao bookDao;

    public BookServiceImpl(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}
XML 复制代码
<?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="bookDao" class="org.example.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl" scope="prototype">
        <constructor-arg name="bookDao" ref="bookDao"/>
    </bean>
</beans>
值类型注入
复制代码
xml中 使用constructor-arg标签 + name + value  name可以换成type或index
java 复制代码
package org.example.service.impl;

import org.example.dao.BookDao;
import org.example.service.BookService;

public class BookServiceImpl implements BookService {
    private int year;
    private String name;

    public BookServiceImpl(int year, String name) {
        this.bookDao = bookDao;
        this.year = year;
        this.name = name;
    }
}
XML 复制代码
<?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="bookDao" class="org.example.dao.impl.BookDaoImpl" />
    <bean id="bookService" class="org.example.service.impl.BookServiceImpl" scope="prototype">
        <constructor-arg name="bookDao" ref="bookDao"/>
        <constructor-arg name="year" value="2024"/>
        <constructor-arg name="name" value="《java入门》"/>
    </bean>
</beans>

自动注入

配置中使用bean标签autowire属性设置自动装配的类型

  • 自动装配用于引用类型依赖注入,不能对简单类型进行操作
  • 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
  • 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
  • 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
复制代码
案例
// 当使用自动注入时,会先找到set方法,然后:
// 1. autowire="byType" 时 会在bean中找到符合BookDao类型的bean来注入
// 2. autowire="byName" 时 会在bean中找到符合名字为 bookDao 的bean来注入

补充:依赖注入bean标签常用属性

spring 集合注入格式-CSDN博客

Bean

bean基础

在Spring框架中,"bean" 是指由Spring IoC(Inversion of Control,控制反转)容器管理的任何对象。Spring IoC容器负责实例化、配置和组装这些bean。简单来说,bean就是应用程序中的一个组件或服务,它是由Spring IoC容器创建并管理的。

以下是关于Spring bean的一些关键点:

  • 定义:通常,你通过在Spring配置文件中使用<bean>标签或者使用注解(如@Component, @Service, @Repository, @Controller等)来定义一个bean。
  • 生命周期管理:Spring容器不仅创建bean,还管理它们的整个生命周期,包括初始化和销毁阶段。你可以通过实现特定的接口(如InitializingBean和DisposableBean)或使用自定义的初始化和销毁方法来控制这个过程。
  • 依赖注入:Spring的一个核心特性是依赖注入(DI, Dependency Injection),它允许你在不直接构造的情况下将一个bean的依赖关系提供给另一个bean。这意味着你不需要在代码中硬编码依赖项,而是可以通过配置让Spring容器自动完成依赖关系的装配。
  • 作用域:每个bean都可以指定一个作用域,比如singleton(单例,每个Spring IoC容器只有一个共享的bean实例)、prototype(原型,每次请求都会产生一个新的bean实例)、request、session等。
  • 配置方式:bean可以通过XML配置文件、Java配置类或注解来定义。随着Spring的发展,基于注解的配置变得越来越流行,因为它更加简洁且易于维护。
  • AOP支持:Spring beans还可以利用Spring AOP(面向切面编程)功能,在运行时动态地添加额外的行为,比如日志记录、事务管理等。

案例

复制代码
<bean id="bookDao" class="org.example.dao.impl.BookDaoImpl" />
<bean id="bookService" class="org.example.service.impl.BookServiceImpl">

bean的别名

获取bean时,可以通过id获取也可以通过别名获取

案例

复制代码
<bean id="bookDao" name="dao,dao1" class="org.example.dao.impl.BookDaoImpl" />
<bean id="bookService" class="org.example.service.impl.BookServiceImpl"/>

bean的作用范围

默认获取的bean是单例模式的

案例

复制代码
<bean id="bookService" class="org.example.service.impl.BookServiceImpl" scope="prototype">
java 复制代码
package org.example;

import org.example.service.BookService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        // 获取IcC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        // 获取bean
        BookService bookService1 = (BookService) ctx.getBean("bookService");
        BookService bookService2 = (BookService) ctx.getBean("bookService");
        System.out.println(bookService1);
        System.out.println(bookService2);
    }
}
输出:scope="prototype" 时获取的bean地址不同
org.example.service.impl.BookServiceImpl@6279cee3
org.example.service.impl.BookServiceImpl@4206a205

由于IoC容器管理的bean是默认是单例模式,哪些类适合交给IoC容器?

适合:

  • 表现层对象
  • 业务层对象
  • 数据层对象
  • 工具对象

不适合

  • 封装实体的域或对象

bean的实例化

无参构造方法实例化bean

bean本质是对象,创建bean使用构造方法完成,且使用的是无参构造方法

静态工厂方法实例化bean

工厂对象方法实例化bean

FactoryBean实例化bean

bean的生命周期

执行生命周期方法一

xml中配置init-mothod 与 destory-mothod

执行生命周期方法二

继承 InitializingBean 与 DisposableBean

手工关闭容器

ConfigurableApplicationcontext接口close()操作

注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机

ConfigurableApplicationcontext接口registerShutdownHook()操作

补充:

获取bean的方式

bean标签常用属性

Spring framework

相关推荐
向宇it4 分钟前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
小蜗牛慢慢爬行7 分钟前
Hibernate、JPA、Spring DATA JPA、Hibernate 代理和架构
java·架构·hibernate
星河梦瑾1 小时前
SpringBoot相关漏洞学习资料
java·经验分享·spring boot·安全
黄名富1 小时前
Redis 附加功能(二)— 自动过期、流水线与事务及Lua脚本
java·数据库·redis·lua
love静思冥想1 小时前
JMeter 使用详解
java·jmeter
言、雲1 小时前
从tryLock()源码来出发,解析Redisson的重试机制和看门狗机制
java·开发语言·数据库
TT哇1 小时前
【数据结构练习题】链表与LinkedList
java·数据结构·链表
机器之心1 小时前
图学习新突破:一个统一框架连接空域和频域
人工智能·后端
Yvemil72 小时前
《开启微服务之旅:Spring Boot 从入门到实践》(三)
java
Anna。。2 小时前
Java入门2-idea 第五章:IO流(java.io包中)
java·开发语言·intellij-idea