初识Spring -- Spring入门保姆级教程(一)

news2024/12/24 20:36:21

文章目录

  • 前言
  • 一、Spring是什么?
    • 1.概述
    • 2.了解spring家族
    • 3.spring系统概述
    • 4.spring优点
    • 5.spring学习路线
  • 二、入门spring
    • 1.核心概念
    • 2.IOC入门案例
    • 3.DI入门案例
    • 4.bean的配置
    • 5.spring 中 bean的实例化--构造方法
    • 6.bean的实例化 -- 静态工厂实例化
    • 7.bean实例化--实例工厂和FactoryBean
    • 8.bean的生命周期
    • 9.依赖注入 -- setter注入
    • 10.依赖注入 -- 构造器注入
    • 11.自动装配
    • 12.数据源对象管理
    • 13.加载properties配置文件
    • 14.IOC容器相关
    • 15.spring入门总结
  • 引用网站及博客
  • 总结


前言

为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。
(博客的参考源码以及可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)


一、Spring是什么?

1.概述

  • Spring Framework 是一个功能强大的 Java 应用程序框架,旨在提供高效且可扩展的开发环境。
  • 它结合了轻量级的容器(IOC)和 依赖注入(DI) 功能,提供了一种使用 POJO 进行容器配置和面向切面的编程的简单方法,以及一组用于 AOP(切面编程) 的模块。
  • Spring 框架还支持各种移动应用开发技术,如 Android 和 iOS。此外,它还提供了对事务管理、对象/关系映射、JavaBeans、JDBC、JMS 和其他技术的支持,从而确保高效开发。

2.了解spring家族

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.spring系统概述

Spring 有可能成为所有企业应用程序的一站式服务点,然而,Spring 是模块化的,允许你挑选和选择适用于你的模块,不必要把剩余部分也引入。下面的部分对在 Spring 框架中所有可用的模块给出了详细的介绍。

Spring 框架提供约 20 个模块,可以根据应用程序的要求来使用。

在这里插入图片描述

  1. 核心容器(Core Container)

核心容器由 spring-core,spring-beans,spring-context,spring-context-support和spring-expression(SpEL,Spring 表达式语言,Spring Expression Language)等模块组成,它们的细节如下:

spring-core 模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。

spring-beans 模块提供 BeanFactory,工厂模式的微妙实现,它移除了编码式单例的需要,并且可以把配置和依赖从实际编码逻辑中解耦。

context 模块建立在由 core和 beans 模块的基础上建立起来的,它以一种类似于 JNDI 注册的方式访问对象。Context 模块继承自 Bean 模块,并且添加了国际化(比如,使用资源束)、事件传播、资源加载和透明地创建上下文(比如,通过 Servelet 容器)等功能。Context 模块也支持 Java EE 的功能,比如 EJB、JMX 和远程调用等。ApplicationContext 接口是 Context 模块的焦点。spring-context-support 提供了对第三方集成到 Spring 上下文的支持,比如缓存(EhCache, Guava, JCache)、邮件(JavaMail)、调度(CommonJ, Quartz)、模板引擎(FreeMarker, JasperReports, Velocity)等。

spring-expression 模块提供了强大的表达式语言,用于在运行时查询和操作对象图。它是 JSP2.1 规范中定义的统一表达式语言的扩展,支持 set 和 get 属性值、属性赋值、方法调用、访问数组集合及索引的内容、逻辑算术运算、命名变量、通过名字从 Spring IoC 容器检索对象,还支持列表的投影、选择以及聚合等。
  1. 数据访问/集成(Data Access/Integration)
    数据访问/集成层包括 JDBC,ORM,OXM,JMS 和事务处理模块,它们的细节如下:

(注:JDBC=Java Data Base Connectivity,ORM=Object Relational Mapping,OXM=Object XML Mapping,JMS=Java Message Service)

JDBC 模块提供了 JDBC 抽象层,它消除了冗长的 JDBC 编码和对数据库供应商特定错误代码的解析。

ORM 模块提供了对流行的对象关系映射 API 的集成,包括 JPA、JDO 和 Hibernate 等。通过此模块可以让这些 ORM 框架和 spring的其它功能整合,比如前面提及的事务管理。

OXM 模块提供了对 OXM 实现的支持,比如 JAXB、Castor、XML Beans、JiBX、XStream 等。

JMS 模块包含生产(produce)和消费(consume)消息的功能。从 Spring 4.1 开始,集成了 spring-messaging 模块。

事务模块为实现特殊接口类及所有的 POJO 支持编程式和声明式事务管理。(注:编程式事务需要自己写 beginTransaction()、commit()、rollback() 等事务管理方法,声明式事务是通过注解或配置由 spring 自动处理,编程式事务粒度更细)
  1. Web

Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下:

Web 模块提供面向 web 的基本功能和面向 web 的应用上下文,比如多部分(multipart)文件上传功能、使用 Servlet 监听器初始化 IoC 容器等。它还包括 HTTP 客户端以及 Spring 远程调用中与 web 相关的部分。

Web-MVC 模块为 web 应用提供了模型视图控制(MVC)和 REST Web服务的实现。Spring 的 MVC 框架可以使领域模型代码和 web 表单完全地分离,且可以与 Spring 框架的其它所有功能进行集成。

Web-Socket 模块为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。

Web-Portlet 模块提供了用于 Portlet 环境的 MVC 实现,并反映了 spring-webmvc 模块的功能。 
  1. Test模块

Test 模块:Spring 支持 Junit 和 TestNG 测试框架,而且还额外提供了一些基于 Spring 的测试功能,比如在测试 Web 框架时,模拟 Http 请求的功能。

  1. 其他

还有其他一些重要的模块,像 AOP,Aspects,Instrumentation,Web 和测试模块,它们的细节如下:

AOP 模块提供了面向方面(切面)的编程实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,从而使实现功能的代码彻底的解耦出来。使用源码级的元数据,可以用类似于.Net属性的方式合并行为信息到代码中。

Aspects 模块提供了与 AspectJ 的集成,这是一个功能强大且成熟的面向切面编程(AOP)框架。

Instrumentation 模块在一定的应用服务器中提供了类 instrumentation 的支持和类加载器的实现。

Messaging 模块为 STOMP 提供了支持作为在应用程序中 WebSocket 子协议的使用。它也支持一个注解编程模型,它是为了选路和处理来自 WebSocket 客户端的 STOMP 信息。

测试模块支持对具有 JUnit 或 TestNG 框架的 Spring 组件的测试

4.spring优点

  • 方便解耦,简化开发

Spring 就是一个大工厂,可以将所有对象的创建和依赖关系的维护交给 Spring 管理

  • 方便集成各种优秀框架

Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如 Struts2、Hibernate、MyBatis 等)的直接支持

  • 降低 Java EE API 的使用难度

Spring 对 Java EE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等)都提供了封装,使这些 API 应用的难度大大降低

  • 方便程序的测试

Spring 支持 JUnit4,可以通过注解方便地测试 Spring 程序

  • AOP 编程的支持

Spring 提供面向切面编程,可以方便地实现对程序进行权限拦截和运行监控等功能

  • 声明式事务的支持

只需要通过配置就可以完成对事务的管理,而无须手动编程。

5.spring学习路线

在这里插入图片描述

二、入门spring

1.核心概念

  1. 依赖注入(DI
  • Spring 最认同的技术是控制反转的依赖注入(DI)模式。控制反转(IoC)是一个通用的概念,它可以用许多不同的方式去表达,依赖注入仅仅是控制反转的一个具体的例子

  • 当编写一个复杂的 Java 应用程序时,应用程序类应该尽可能的独立于其他的 Java 类来增加这些类可重用可能性,当进行单元测试时,可以使它们独立于其他类进行测试。依赖注入(或者有时被称为配线)有助于将这些类粘合在一起,并且在同一时间让它们保持独立。

  • 到底什么是依赖注入?让我们将这两个词分开来看一看。这里将依赖关系部分转化为两个类之间的关联。例如,类 A 依赖于类 B。现在,让我们看一看第二部分,注入。所有这一切都意味着类 B 将通过 IoC 被注入到类 A 中。

  • 依赖注入可以以向构造函数传递参数的方式发生,或者通过使用 setter 方法 post-construction。由于依赖注入是 Spring 框架的核心部分,所以我将在一个单独的章节中利用很好的例子去解释这一概念。

2.面向切面的程序设计(AOP):

  • Spring 框架的一个关键组件是面向切面的程序设计(AOP)框架。一个程序中跨越多个点的功能被称为横切关注点,这些横切关注点在概念上独立于应用程序的业务逻辑。有各种各样常见的很好的关于方面的例子,比如日志记录、声明性事务、安全性,和缓存等等。

  • 在 OOP 中模块化的关键单元是类,而在 AOP 中模块化的关键单元是方面。AOP 帮助你将横切关注点从它们所影响的对象中分离出来,然而依赖注入帮助你将你的应用程序对象从彼此中分离出来。

  • Spring 框架的 AOP 模块提供了面向方面的程序设计实现,可以定义诸如方法拦截器和切入点等,从而使实现功能的代码彻底的解耦出来。使用源码级的元数据,可以用类似于 .Net 属性的方式合并行为信息到代码中。我将在一个独立的章节中讨论更多关于 Spring AOP 的概念。

  1. Spring IoC 容器
  • Spring 容器是 Spring 框架的核心。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。Spring 容器使用依赖注入(DI)来管理组成一个应用程序的组件。这些对象被称为 Spring Beans

  • 通过阅读配置元数据提供的指令,容器知道对哪些对象进行实例化,配置和组装。配置元数据可以通过 XML,Java 注释或 Java 代码来表示。下图是 Spring 如何工作的高级视图。 Spring IoC 容器利用 Java 的 POJO 类和配置元数据来生成完全配置和可执行的系统或应用程序

在这里插入图片描述

  • IOC 容器具有依赖注入功能的容器,它可以创建对象,IOC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。通常new一个实例,控制权由程序员控制,而"控制反转"是指new实例工作不由程序员来做而是交给Spring容器来做。在Spring中BeanFactory是IOC容器的实际代表者。

  • Spring 提供了以下两种不同类型的容器。

序号容器 & 描述
1Spring BeanFactory 容器 :它是最简单的容器,给 DI 提供了基本的支持,它用 org.springframework.beans.factory.BeanFactory 接口来定义。BeanFactory 或者相关的接口,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的与 Spring 整合的第三方框架的反向兼容性的目的。
2Spring ApplicationContext 容器 :该容器添加了更多的企业特定的功能,例如从一个属性文件中解析文本信息的能力,发布应用程序事件给感兴趣的事件监听器的能力。该容器是由 org.springframework.context.ApplicationContext 接口定义。

ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常不建议使用BeanFactory。BeanFactory 仍然可以用于轻量级的应用程序,如移动设备或基于 applet 的应用程序,其中它的数据量和速度是显著。

  1. Spring Bean 定义
  • 被称作 bean 的对象是构成应用程序的支柱也是由 Spring IoC 容器管理的。bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象。这些 bean 是由用容器提供的配置元数据创建的,例如,已经在先前章节看到的,在 XML 的表单中的 定义。

  • bean 定义包含称为配置元数据的信息,下述容器也需要知道配置元数据:

    • 如何创建一个 bean

    • bean 的生命周期的详细信息

    • bean 的依赖关系

上述所有的配置元数据转换成一组构成每个 bean 定义的下列属性。

属性描述
class这个属性是强制性的,并且指定用来创建 bean 的 bean 类。
name这个属性指定唯一的 bean 标识符。在基于 XML 的配置元数据中,你可以使用 ID 和/或 name 属性来指定 bean 标识符。
scope这个属性指定由特定的 bean 定义创建的对象的作用域,它将会在 bean 作用域的章节中进行讨论。
constructor-arg它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
properties它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
autowiring mode它是用来注入依赖关系的,并会在接下来的章节中进行讨论。
lazy-initialization mode延迟初始化的 bean 告诉 IoC 容器在它第一次被请求时,而不是在启动时去创建一个 bean 实例。
initialization 方法在 bean 的所有必需的属性被容器设置之后,调用回调方法。它将会在 bean 的生命周期章节中进行讨论。
destruction 方法当包含该 bean 的容器被销毁时,使用回调方法。它将会在 bean 的生命周期章节中进行讨论。
  • Bean 与 Spring 容器的关系

在这里插入图片描述## 5.spring三层架构

A 表现层   web层    MVC是表现层的一个设计模型 

B 业务层  service层

C 持久层  dao层

2.IOC入门案例

  1. 入门案例思路分析

在这里插入图片描述

  1. 创建maven模块

在这里插入图片描述

  1. 编写接口和Dao实现类(此时无spring环境,纯JAVA开发)
  • 模块代码结构
    在这里插入图片描述

  • BookDao

public interface BookDao {
    public void save();
}

  • BookDaoImpl
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
}

  • BookService
public interface BookService {
    public void save();
}
  • BookServiceImpl
public class BookServiceImpl implements BookService {
    private BookDao bookDao = new BookDaoImpl();

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
}
  • Main
public class Main {
    public static void main(String[] args) {
        BookService bookService = new BookServiceImpl();
        bookService.save();
    }
}
  • Main类运行结果

在这里插入图片描述

  1. 示例代码解析
  • 首先写了两个数据层接口 BookDao 和 BookService,两个接口中都定义了save()方法
  • 然后写了两个数据层接口的实现类 BookDaoImpl 和 BookServiceImpl,分别实现了save() 方法,方法里都要一条输出语句,但是两个实现类save方法打印的内容不同
  • 其中 BookServiceImpl 类中还通过new创建对象的方式调用了 BookDaoImpl的save方法
  • 最后在Main类中通过new创建对象的方式调用了BookServiceImpl的save方法将两个save()方法中的语句打印了出来
  1. 在pom.xml中导入spring坐标spring-context
 <dependencies>
        <!--spring坐标-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.21.RELEASE</version>
        </dependency>
    </dependencies>

  1. 创建spring核心配置文件applicationContext.xml

resources 目录右键 --> new --> XML Configuration File --> Spring Config(导入spring坐标后才有对应选项)

在这里插入图片描述

  1. 配置Bean(如下)
<?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">

       <!--1.导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->

       <!--2.配置bean-->
       <!--bean标签标示配置bean
       id属性标示给bean起名字
       class属性表示给bean定义类型-->
       <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>

       <bean id="bookService" class="org.example.service.impl.BookServiceImpl"/>
               
</beans>
  1. 在org.example下新建一个类Main2
public class Main2 {
    public static void main(String[] args) {
        //3.获取IoC容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        //4.获取bean(根据bean配置id获取)
        //左边是对象,右边是接口,所以要强转类型
        BookDao bookDao = (BookDao) ctx.getBean("bookDao");
        bookDao.save();

        BookService bookService = (BookService) ctx.getBean("bookService");
        bookService.save();
    }
}
  • 程序运行结果(通过spring创建对象而不是通过new创建对象)

在这里插入图片描述

  1. 总结 :spring程序的开发步骤

在这里插入图片描述

3.DI入门案例

  1. 删除BookServiceImpl类中通过new方式创建对象的代码,并提供对应的setter方法
package org.example.service.impl;

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

public class BookServiceImpl implements BookService {
    //5.删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;
//    private BookDao bookDao = new BookDaoImpl();

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    //    6.提供对应的set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

  1. 在全局配置文件applicationContext.xml文件中将BookDao注入到BookService中
<?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">

       <!--1.导入spring的坐标spring-context,对应版本是5.2.10.RELEASE-->

       <!--2.配置bean-->
       <!--bean标签标示配置bean
       id属性标示给bean起名字
       class属性表示给bean定义类型-->
       <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>

       <bean id="bookService" class="org.example.service.impl.BookServiceImpl">
       <!--7.配置server与dao的关系-->
       <!--property标签表示配置当前bean的属性
       name属性表示配置哪一个具体的属性
       ref属性表示参照哪一个bean-->
       <property name="bookDao" ref="bookDao"/>
       </bean>

</beans>

  1. 运行结果

在这里插入图片描述

  1. 注意事项

name 的值是类的属性值,ref的值是id值

在这里插入图片描述

4.bean的配置

  1. bean的基础配置

在这里插入图片描述

  1. bean的别名设置

在这里插入图片描述

  1. 控制bean的作用范围

在这里插入图片描述

5.spring 中 bean的实例化–构造方法

  1. 创建新的maven模块respr_newbean,并在pom.xml添加spring的坐标

在这里插入图片描述

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.22</version>
            <scope>compile</scope>
        </dependency>
  1. 创建核心配置文件applicationContext.xml文件、dao接口及其实现类以及相关的类(先写标记部分)

在这里插入图片描述

  1. 编写dao接口及其实现类
  • BookDao接口
public interface BookDao {
    public void save();
}

  • BookDaoImpl实现类
public class BookDaoImpl implements BookDao {
    //无参构造
    public BookDaoImpl() {
        System.out.println("book dao constructor is running ....");
    }

    public void save() {
        System.out.println("book dao save ...");
    }

}

  • 进行测试的类 AppForInstanceBook
public class AppForInstanceBook {
    public static void main(String[] args) {

        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        BookDao bookDao = (BookDao) ctx.getBean("bookDao");

        bookDao.save();

    }
}

  • applicationContext.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-->
    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>

</beans>

  • AppForInstanceBook运行结果

在这里插入图片描述

  • 结论

spring构造方法实例化bean使用了无参构造器,可以省略无参构造器的书写。实例化bean就是用构造方法来实例化对象。

6.bean的实例化 – 静态工厂实例化

  1. 创建dao接口及其实现类以及相关的类(先写标记部分)

在这里插入图片描述

  1. 编写dao接口及其实现类以及相关的类
  • OrderDao接口
package org.example.dao;

public interface OrderDao {
    public void save();
}

  • OrderDaoImpl实现类
在这里插入代码片package org.example.dao.impl;

import org.example.dao.OrderDao;

public class OrderDaoImpl implements OrderDao {

    public void save() {
        System.out.println("order dao save ...");
    }
}

  • 工厂类OrderDaoFactory(静态工厂类代理生成对象)
package org.example.factory;

import org.example.dao.OrderDao;
import org.example.dao.impl.OrderDaoImpl;
//静态工厂创建对象
public class OrderDaoFactory {
    public static OrderDao getOrderDao(){
        System.out.println("factory setup....");
        return new OrderDaoImpl();
    }
}

  • AppForInstanceOrder模拟测试类编写(纯JAVA开发,此处还没有Spring)
public class AppForInstanceOrder {
    public static void main(String[] args) {
        //通过静态工厂创建对象
        OrderDao orderDao = OrderDaoFactory.getOrderDao();
        orderDao.save();

    }
}
  • 模拟测试类的运行结果

在这里插入图片描述

  • 简要分析

将 OrderDaoImpl 创建对象的 工作交给 静态工厂 OrderDaoFactory 类来完成,如果用spring代理这种工厂模式的开发,写法如下

  • spring 代理静态工厂实例化对象
public class AppForInstanceOrder {
    public static void main(String[] args) {
        //通过静态工厂创建对象
//        OrderDao orderDao = OrderDaoFactory.getOrderDao();
//        orderDao.save();

//      spring代理静态工厂实例化对象
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        OrderDao orderDao = (OrderDao) ctx.getBean("orderDao");

        orderDao.save();

    }
}

  • applicationContext.xml文件配置静态工厂 OrderDaoFactory bean (注意factory-method属性)
<?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-->
<!--    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>-->


<!--    方式二:使用静态工厂实例化bean-->
    <bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>

</beans>

  • 运行结果

在这里插入图片描述

7.bean实例化–实例工厂和FactoryBean

  1. 创建dao接口及其实现类以及相关的类(标记部分)

在这里插入图片描述

  1. 编写dao接口及其实现类以及相关的类
  • UserDao接口
public interface UserDao {
    public void save();
}

  • UserDaoImpl实现类
public class UserDaoImpl implements UserDao {

    public void save() {
        System.out.println("user dao save ...");
    }
}

  • UserDaoFactoryBean实例工厂类
//实例工厂创建对象
public class UserDaoFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}


  • AppForInstanceUser模拟测试类(纯JAVA开发)
public class AppForInstanceUser {
    public static void main(String[] args) {
//        //创建实例工厂对象
        UserDaoFactory userDaoFactory = new UserDaoFactory();
//        //通过实例工厂对象创建对象
        UserDao userDao = userDaoFactory.getUserDao();
        userDao.save();

    }
}

  1. 运行结果

在这里插入图片描述

  1. 简要分析

此时与静态工厂的区别是模拟测试类中多了创建工厂对象的步骤

  • spring代理下的实例工厂bean实例化模拟测试类
public class AppForInstanceUser {
    public static void main(String[] args) {
//        //创建实例工厂对象
//        UserDaoFactory userDaoFactory = new UserDaoFactory();
//        //通过实例工厂对象创建对象
//        UserDao userDao = userDaoFactory.getUserDao();
//        userDao.save();


        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserDao userDao = (UserDao) ctx.getBean("userDao");

        userDao.save();
        
    }
}

  1. applicationContext.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-->
    <!--    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>-->


    <!--    方式二:使用静态工厂实例化bean-->
<!--    <bean id="orderDao" class="org.example.factory.OrderDaoFactory" factory-method="getOrderDao"/>-->

    <!--方式三:使用实例工厂实例化bean-->
        <bean id="userFactory" class="org.example.factory.UserDaoFactory"/>

        <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>

</beans>

  1. 模拟测试类运行结果

在这里插入图片描述

  1. spring代理实例工厂bean实例化简要分析 --> 改进为BeanFactory bean实例化

在这里插入图片描述

  1. 创建并编写BeanFactory工厂类UserDaoFactoryBean
//FactoryBean创建对象
//实现接口,创建什么对象写什么泛型
public class UserDaoFactoryBean implements FactoryBean<UserDao> {
    //实现抽象方法

    //代替原始实例工厂中创建对象的方法,以后方法名不用指定,就用getObject
    public UserDao getObject() throws Exception {
        return new UserDaoImpl();
    }

    //配置的类是什么类型
    public Class<?> getObjectType() {
        return UserDao.class;
    }

}

  1. 配置applicationContext.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-->
    <!--    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl"/>-->


    <!--    方式二:使用静态工厂实例化bean-->
<!--    <bean id="orderDao" class="org.example.factory.OrderDaoFactory" factory-method="getOrderDao"/>-->

    <!--方式三:使用实例工厂实例化bean-->
<!--        <bean id="userFactory" class="org.example.factory.UserDaoFactory"/>-->

<!--        <bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>-->

    <!--方式四:使用FactoryBean实例化bean-->
    <bean id="userDao" class="org.example.factory.UserDaoFactoryBean"/>

</beans>

  1. 模拟测试类运行结果

在这里插入图片描述

8.bean的生命周期

  1. 概念

在这里插入图片描述

  • 理解 Spring bean 的生命周期很容易。当一个 bean 被实例化时,它可能需要执行一些初始化使它转换成可用状态。同样,当 bean 不再需要,并且从容器中移除时,可能需要做一些清除工作

  • 尽管还有一些在 Bean 实例化和销毁之间发生的活动,有两个重要的生命周期回调方法,它们在 bean 的初始化销毁的时候是必需的

  • 为了定义安装和拆卸一个 bean,我们只要声明带有 init-method 和/或 destroy-method 参数的 。init-method 属性指定一个方法,在实例化 bean 时,立即调用该方法。同样,destroy-method 指定一个方法,只有从容器中移除 bean 之后,才能调用该方法

  • Bean的生命周期可以表达为:Bean的定义——Bean的初始化——Bean的使用——Bean的销毁

  1. 编写代码(IOC 和 DI入门案例的代码,模块名为respr_ioc)
  • 在BookDaoImpl实现类中定义代表创建bena初始化和销毁的方法
package org.example.dao.impl;

import org.example.dao.BookDao;

public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save ...");
    }
    //表示bean初始化对应的操作
    public void init(){
        System.out.println("init...");
    }
    //表示bean销毁前对应的操作
    public void destory(){
        System.out.println("destory...");
    }
}

  1. 在applicationContext.xml文件中配置BookDao bean 的 初始化方法 int-method 和销毁方法 destory-method

在这里插入图片描述

  1. 将BookService的代码注释掉,运行模拟测试类,观察BookDao bean的创建和销毁过程

在这里插入图片描述

  • 运行结果

在这里插入图片描述

  1. 简要分析
    我们从运行结果可以看到bean初始化成功了,但是并没有进行销毁工作,原因是java虚拟机(java在虚拟机运行)在执行玩程序退出时并没有做销毁操作,我们需要自己添加关闭语句,ctx.close()。但是ApplicationContext接口中并没有这个方法,而它的实现类中有,所以我们要用它的实现类ClassPathXmlApplicationContext来调用这个方法

  2. 关闭ioc容器的代码及运行结果如下

在这里插入图片描述

  1. 关闭ioc容器的第二种方式:关闭钩子(概念、代码及运行结果如下)

在Java程序退出时——尤其是非正常退出时,我们可能需要先执行一些善后工作,如关闭线程池、连接池、文件句柄等。如何保证善后工作的代码能够被执行到呢?Java为用户提供了关闭钩子(shutdown hook)registerShutdownHook()方法来注册关闭钩子

在这里插入图片描述

  1. 两种关闭ioc容器的简要分析
    关闭钩子函数代码在程序中的位置要求没有close()方法那么苛刻,如果将其挪到bookDao.save()方法的下面也能用,close()方法比较暴力

  2. 绑定销毁方法和初始化方法的改进–继承接口(以BookServiceImpl为例)

  • 实现InitializingBean, DisposableBean接口
  • 重写 destroy(销毁) 和 afterPropertiesSet(初始化) 方法
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
    private BookDao bookDao;

    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

    public void destroy() throws Exception {
        System.out.println("service destroy");
    }

    public void afterPropertiesSet() throws Exception {
        System.out.println("service init");
    }
}

  1. 模拟测试类Main2运行结果

(尽管在模拟测试类Main2并没有调用BookService 的bean,但是在核心配置文件中定义了BookService 的 bean,该创建bean的时候就创建,该初始化就初始化,该销毁就销毁)

在这里插入图片描述

9.依赖注入 – setter注入

  1. 思考

在这里插入图片描述

  1. 依赖注入 – setter注入引用类型的步骤方法(DI入门案例所用的就是setter注入引用类型)

在这里插入图片描述(代码见DI入门案例)

  1. 探讨引用多个引用对象(在DI入门的代码基础上编码)
  • 在dao包下创建并编写UserDao接口
package org.example.dao;

public interface UserDao {
    public void save();
}

  • 在impl包下创建并编写UserDaoImpl实现类
package org.example.dao.impl;

import org.example.dao.UserDao;

public class UserDaoImpl implements UserDao {
    public void save() {
        System.out.println("user dao save ...");
    }
}

  • 在BookServiceImpl实现类中setter注入UserDao
public class BookServiceImpl implements BookService{
    private BookDao bookDao;
    private UserDao userDao;
    //setter注入需要提供要注入对象的set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    //setter注入需要提供要注入对象的set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
        userDao.save();
    }
}

  • 在核心配置类applicationContext中配置userDAO的bean,并将其注入到BookService中

在这里插入图片描述

  • 执行模拟测试类App2

在这里插入图片描述
(从运行结果中可以看到多个引用类型是可以用setter注入的)

  1. 依赖注入 – setter注入普通类型的步骤方法

在这里插入图片描述

  1. 在BookDaoImpl中提供两个变量,并提供对应的setter方法(以BookDaoImpl为例)
public class BookDaoImpl implements BookDao {

    private String databaseName;
    private int connectionNum;
    //setter注入需要提供要注入对象的set方法
    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }
    //setter注入需要提供要注入对象的set方法
    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }

    public void save() {
        System.out.println("book dao save ..."+databaseName+","+connectionNum);
    }
}

  • 在核心配置类applicationContext.xml文件中配置中注入普通变量

在这里插入图片描述

  • 模拟测试类App2类的运行结果

在这里插入图片描述

10.依赖注入 – 构造器注入

(在依赖注入–setter注入的基础上编码,将依赖注入相关的代码删掉,具体见个人主页上传的代码respr_diconstouctor)

1 . 依赖注入 – 构造器注入引用类型的步骤方法

在这里插入图片描述

  1. 在BookService类中提供构造方法
public class BookServiceImpl implements BookService {
    //5.删除业务层中使用new的方式创建的dao对象
    private BookDao bookDao;

    //提供构造方法
    public BookServiceImpl(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }

}

  1. 在核心配置类中注入BookDao相关的bean
<?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">
        <constructor-arg name="bookDao" ref="bookDao"/>
    </bean>

</beans>
  1. 模拟测试类App2运行结果(同理,构造器注入可以注入多个引用类型,此处省略相关代码)

在这里插入图片描述

  1. 依赖注入 – 构造器注入普通类型的步骤和方法

在这里插入图片描述

  1. 在BookDao中定义两个变量,并编写对应的构造器方法
public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;

    public BookDaoImpl(String databaseName, int connectionNum) {
        this.databaseName = databaseName;
        this.connectionNum = connectionNum;
    }

    public void save() {
        System.out.println("book dao save ..."+databaseName+","+connectionNum);
    }
}

  1. 在核心配置文件配置相关属性
  • 方式一:根据构造方法参数名称注入

在这里插入图片描述

  • 方式二:根据构造方法参数类型注入

在这里插入图片描述

  • 方式三:根据构造方法参数位置注入

在这里插入图片描述

  1. 模拟测试类App2运行结果

在这里插入图片描述

  1. 依赖注入的选择

在这里插入图片描述

11.自动装配

  1. 自动装配基础知识
  • 我们已经学会如何使用元素来声明 bean 和通过使用 XML 配置文件中的和元素来注入 。

  • Spring 容器可以在不使用和 元素的情况下自动装配相互协作的 bean 之间的关系,这有助于减少编写一个大的基于 Spring 的应用程序的 XML 配置的数量。

  • 下列自动装配模式,它们可用于指示 Spring 容器为来使用自动装配进行依赖注入。你可以使用元素的 autowire 属性为一个 bean 定义指定自动装配模式。

模式描述
no这是默认的设置,它意味着没有自动装配,你应该使用显式的bean引用来连线。你不用为了连线做特殊的事。在依赖注入章节你已经看到这个了。
byName(按名称)由属性名自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byName。然后尝试匹配,并且将它的属性与在配置文件中被定义为相同名称的 beans 的属性进行连接。
byType(按类型)由属性数据类型自动装配。Spring 容器看到在 XML 配置文件中 bean 的自动装配的属性设置为 byType。然后如果它的类型匹配配置文件中的一个确切的 bean 名称,它将尝试匹配和连接属性的类型。如果存在不止一个这样的 bean,则一个致命的异常将会被抛出。
constructor类似于 byType,但该类型适用于构造函数参数类型。如果在容器中没有一个构造函数参数类型的 bean,则一个致命错误将会发生。
autodetect(3.0版本不支持)Spring首先尝试通过 constructor 使用自动装配来连接,如果它不执行,Spring 尝试通过 byType 来自动装配。

可以使用 byType 或者 constructor 自动装配模式来连接数组和其他类型的集合。

  1. 在入门案例的基础上编码(详情见个人主页spring代码资源respr_autowire模块)

在这里插入图片描述

  1. 自动装配
  • 手动配置

在这里插入图片描述

  • 按类型自动装配(byType)

在这里插入图片描述

(需要提供setter方法,ioc通过setter入口给bean)

在这里插入图片描述

  • 按名称装配

(要确保BookDao装配bean的id与BookService中的其中一个属性名对应上)
在这里插入图片描述

  • 依赖自动装配特征

在这里插入图片描述

  • 集合注入(比较少用)(数组,List,Set,Map,properties)

  • 新建BookDao2接口及其实现类

package org.example.dao;

public interface BookDao2 {
    public void save();
}

public class BookDaoImpl2 implements BookDao2 {

    //数组
    private int[] array;
    //列表
    private List<String> list;
    //集合
    private Set<String> set;
    //图
    private Map<String,String> map;
    //properties
    private Properties properties;
    //提供对应的setter方法作为ioc提供bean的入口
    public void setArray(int[] array) {
        this.array = array;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    //编写测试方法
    public void save() {
        System.out.println("book dao save ...");

        System.out.println("遍历数组:" + Arrays.toString(array));

        System.out.println("遍历List" + list);

        System.out.println("遍历Set" + set);

        System.out.println("遍历Map" + map);

        System.out.println("遍历Properties" + properties);
    }
}

  • 核心配置类文件编写
<?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" autowire="byName"/>-->

    <bean id="bookDao2" class="org.example.dao.impl.BookDaoImpl2">

    <!--数组注入-->
    <property name="array">
        <array>
            <value>100</value>
            <value>200</value>
            <value>300</value>
        </array>
    </property>
    <!--list集合注入-->
    <property name="list">
        <list>
            <value>itcast</value>
            <value>itheima</value>
            <value>boxuegu</value>
            <value>chuanzhihui</value>
        </list>
    </property>
    <!--set集合注入-->
    <property name="set">
        <set>
            <value>itcast</value>
            <value>itheima</value>
            <value>boxuegu</value>
            <value>boxuegu</value>
        </set>
    </property>
    <!--map集合注入-->
    <property name="map">
        <map>
            <entry key="country" value="china"/>
            <entry key="province" value="henan"/>
            <entry key="city" value="kaifeng"/>
        </map>
    </property>
    <!--Properties注入-->
    <property name="properties">
        <props>
            <prop key="country">china</prop>
            <prop key="province">henan</prop>
            <prop key="city">kaifeng</prop>
        </props>
    </property>
    </bean>

</beans>
  • 模拟测试类编写及运行结果

在这里插入图片描述

12.数据源对象管理

  1. 导入数据源坐标(以druid数据源为例)
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
  1. 在核心配置文件中配置管理数据源对象(由于第三方技术已经写好,注入方式以及具体属性名需要查
<bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring_db"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
  1. 创建编写模拟配置类App及其运行结果
public class App {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource);
        
    }
}

在这里插入图片描述

13.加载properties配置文件

  1. 在resources目录下创建jdbc.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/spring_db
jdbc.username=root
jdbc.password=root
  1. 在核心配置类中开启context命名空间

在这里插入图片描述

  1. 使用context空间加载properties文件
<?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
            ">

<!--    1.开启context命名空间-->
<!--    2.使用context空间加载properties文件-->
<!--    属性占位符,location:加载的文件-->
    <context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
<!--    3.使用属性占位符${}读取properties文件中的属性-->
<!--    说明:idea自动识别${}加载的属性值,需要手工点击才可以查阅原始书写格式-->
    <bean class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <bean id="bookDao" class="org.example.dao.impl.BookDaoImpl">
        <property name="name" value="${jdbc.driver}"/>
    </bean>

</beans>
  1. 将绑定好的properties属性注入到bookdao中,通过bookdao中的save方法输出
public interface BookDao {
    public void save();
}

public class BookDaoImpl implements BookDao {
    private String name;

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

    public void save() {
        System.out.println("book dao save ..." + name);
    }
}

  1. 模拟测试类及输出结果

在这里插入图片描述
6. 小结和拓展

在这里插入图片描述
在这里插入图片描述

14.IOC容器相关

  1. 创建容器

在这里插入图片描述

  1. 获取bean的方式

在这里插入图片描述

  1. 容器类层次结构

(BeanFactory接口创建完毕后,所有的bean均为延迟加载)

在这里插入图片描述

15.spring入门总结

  1. IOC容器相关

在这里插入图片描述

  1. bean相关

在这里插入图片描述

  1. 依赖注入相关

在这里插入图片描述

16.Spring整合Junit

在这里插入图片描述

引用网站及博客

1.【w3cschool】
2. 【sprign教学视频】

总结

欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下。
(博客的参考源码可以在我主页的资源里找到,如果在学习的过程中有什么疑问欢迎大家在评论区向我提出)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/581951.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IEEE802.3和IEEE802.11的分类(仅为分类)

IEEE802.3标准 IEEE802.3:10兆以太网 ●10Base&#xff0d;5 使用粗同轴电缆&#xff0c;最大网段长度为500m&#xff0c;基带传输方法&#xff1b; ●10Base&#xff0d;2 使用细同轴电缆&#xff0c;最大网段长度为185m&#xff0c;基带传输方法&#xff1b; ●10Base&am…

python+vue宠物用品商城网站django宠物领养系统31e70

我们也变得越来越忙碌、对生活的要求也变得更加严格&#xff0c;对快速和方便的服务的需求也在逐渐增加。因此&#xff0c;对宠物行业的管理、服务的要求也越来越严格。为适应时代的发展&#xff0c;各大宠物店开始广泛地使用电脑来进行管理&#xff0c;并推出在线宠物管理系统…

华为OD机试真题B卷 Java 实现【去除多余空格】,附详细解题思路

一、题目描述 去除文本多余空格&#xff0c;但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标&#xff0c;去除多余空格后刷新关键词的起始和结束下标。 条件约束&#xff1a; 不考虑关键词起始和结束位置为空格的场景&#xff1b;单词的的开始和结束下标保证…

100天精通Python(可视化篇)——第89天:Bokeh库绘图可视化基础入门(参数说明+案例实战)

文章目录 专栏导读一、Bokeh是什么&#xff1f;二、安装与导入三、Bokeh接口介绍四、创建图表五、添加自定义渲染器切换主题添加图例图例位置图例方向图例背景和边界图例文本的外观行列布局网格布局 专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到…

十万个C语言冷知识

1.printf返回值&#xff1a; 成功&#xff1a;返回打印字符的个数 失败&#xff1a;返回EOF&#xff0c;EOF是文件结束的标志&#xff0c;宏定义为-1 #include <stdio.h> int main() {char str[] "123456789";printf("%d\n", printf("%d\n&quo…

效率神器AutoHotKey的初步使用

文章目录 下载安装与体验快捷键在程序中的热键热字串和重映射实战 Python命令行 下载安装与体验 下载AHK&#xff0c;安装后&#xff0c;右键->新建->AutoHotkey脚本&#xff0c;内容为 #space::Run tinycool.blog.csdn.net其中&#xff0c;#表示Win键&#xff1b;#spa…

Rust每日一练(Leetday0014) 组合总和II、缺失正数、接雨水

目录 40. 组合总和 II Combination Sum II &#x1f31f;&#x1f31f; 41. 缺失的第一个正数 First Missing Positive &#x1f31f;&#x1f31f;&#x1f31f; 42. 接雨水 Trapping Rain Water &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题…

Web 自动化测试案例(入门级)——关闭某视频网站弹出广告以及打开登录框输入内容

文章目录 &#x1f4cb;前言&#x1f3af;自动化测试&#x1f9e9;环境的搭建 &#x1f3af;案例介绍&#x1f4dd;最后 &#x1f4cb;前言 人生苦短&#xff0c;我用Python。许久没写博客了&#xff0c;今天又是久违的参与话题的讨论&#xff0c;话题的内容是&#xff1a;如何…

基于springboot注解的shiro 授权及角色认证

目录 授权 后端接口服务注解 授权验证-没有角色无法访问 授权验证-获取角色进行验证 授权验证-获取权限进行验证 授权验证-异常处理 授权 用户登录后&#xff0c;需要验证是否具有指定角色指定权限。Shiro也提供了方便的工具进行判 断。 这个工具就是Realm的doGetAuthor…

华为OD机试真题B卷 Java 实现【狼羊过河】,附详细解题思路

一、题目描述 一农夫带着m只羊&#xff0c;n只狼过河&#xff0c;农夫有一条可载x只狼/羊的船&#xff1b;农夫在时或者羊的数量大于狼时&#xff0c;狼不会攻击羊&#xff1b; 农夫在不损失羊的情况下&#xff0c;运输几次可以完成运输&#xff1f; 返程不计入次数。 二、…

K8s容器运行环境安全加固

K8s容器运行环境安全加固 目录 文章目录 K8s容器运行环境安全加固目录1、最小特权原则&#xff08;POLP&#xff09;2、AppArmor限制容器对资源访问3、Seccomp 限制容器进程系统调用关于我最后 1、最小特权原则&#xff08;POLP&#xff09; **最小特权原则 (Principle of lea…

graalvm把java编译为c/c++能够使用的动态库(dll/so)

graalvm把java编译为c/c能够使用的动态库(dll/so) 1.安装graalvm oracle官方企业版 github的openjdk版本 1.1 下载对应系统版本&#xff0c;配置环境变量 本人环境 1. win10 openjdk 17.0.5 2022-10-18 OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.58-jv…

chatgpt赋能python:Python中的None值如何去掉?

Python中的None值如何去掉&#xff1f; Python是一种具有高度灵活性和可读性的编程语言&#xff0c;它有许多强大的功能&#xff0c;令许多开发人员喜欢使用它。然而&#xff0c;可能会遇到延迟或者None值的情况&#xff0c;这时需要我们找到正确的方法去除它们。 None值是什…

C#,码海拾贝(27)——求解“对称方程组”的“分解法”之C#源代码,《C#数值计算算法编程》源代码升级改进版

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 求解线性方程组的类 LEquations /// 原作 周长发 /// 改编 深度混淆 /// </summary> public static partial class LEquations { /// <summary> /…

happens-before规则

happens-before背景由来 happens-before的概念最初由Leslie Lamport在其一篇影响深远的论文&#xff08;《Time&#xff0c;Clocks and the Ordering of Events in a Distributed System》&#xff09;中提出。Leslie Lamport使用 happens-before 来定义分布式系统中事件之间…

【利用AI让知识体系化】7种结构型模式

文章目录 结构型模式简介适配器模式装饰器模式代理模式外观模式桥接模式组合模式享元模式 结构型模式 简介 在设计模式中&#xff0c;结构型模式用于描述如何将对象和类组装成较大的结构&#xff0c;并灵活地处理对象之间的关系。 结构型模式包括以下几种&#xff1a; 适配器…

驱动开发——嵌入式(驱动)软开基础(十)

1. 64位的计算机有哪些优点&#xff1f; &#xff08;1&#xff09;可以进行更大范围的整数计算。 &#xff08;2&#xff09;可以支持更大的内存&#xff0c;虚拟内存空间大小一般为2^48&#xff08;256TB&#xff09;。64位的Linux一般使用48位表示虚拟内存空间地址&#x…

esp8266 OTA远程无线升级

第一步、编译生成.bin升级固件 本教程需要用到 arduino IDE的esp8266开发环境,关于arduino IDE 的ESP8266环境配置可参考:环境配置: 点击跳转 如果已安装好esp8266 开发环境,继续: 使用arduino IDE软件,打开随便一个需要升级的程序,点击「项目」-「导出已编译的二进制…

【Bug 全解决】 Java、Spring boot 后端项目 Bug 总结

Bug 收集与总结 本文记录的是 SpringBoot 后端项目使用和运行代码时所遇到的各种问题&#xff0c;全部都已解决&#xff0c;欢迎在评论区补充你遇到的 Bug 哦&#xff01;仅以本文记录学习社区项目时&#xff0c;所遇到的奇奇怪怪的 bug&#xff0c;以及一些很愚蠢的错误&…

Golang每日一练(leetDay0080) 矩形面积、翻转二叉树

目录 223. 矩形面积 Rectangle Area &#x1f31f;&#x1f31f; 226. 翻转二叉树 Invert Binary Tree &#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏…