1、Spring简介与基于XML的IoC装配

news2025/4/27 5:27:54

一、Sping简介

1、概述

1、Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。
2、Spring是一个面向对象设计层面的开发框架(基本上都是运行在后台),其本身提供有一个完善的设计容器,利用此容器可以帮助开发者实现对象的管理、线程同步处理、依赖关系的配置等。
3、Spring官网
4、官方项目和文档
5、Spring的归档文档
6、 Spring的官方Github

2、Spring框架特点

1、非侵入式:基于Spring开发的应用中的对象可以不依赖与Spring的API
2、控制反转:IoC(Inversion of control),指的是将对象的创建权交由Spring框架来管理,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系。在使用Spring之前,对象的创建都是在代码中new创建。
3、依赖注入:DI(Dependency Injection),应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。依赖的对象不需要手动调用setXXX方法去设置值,通过配置自动赋值。
4、容器:Spring负责创建和管理对象(Bean)的生命周期和配置。
5、面向切面编程:AOP(Aspect Oriented Programming),能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。
6、组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在Spring中可以使用XML和Java注解组合这些对象。

3、Spring体系结构

在这里插入图片描述

1、Code Container(Spring的核心容器):
2、Data Access/Integration(数据访问/集成):
3、Web模块:
4、AOP、Aspects、Instrumentation和Messaging模块:
5、Test模块:Spring支持Junit和TestNG测试框架,而且还额外提供了一些基于Spring的测试功能,比如在测试Web框架时,模拟Http请求的功能。

二、Spring简单示例搭建

1、创建一个Maven工程

1、新建一个Project

在这里插入图片描述

2、填写好信息,点击结束

在这里插入图片描述

2、引入Spring的POM依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>Learning</artifactId>
        <groupId>com.itan</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>spring-core</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <spring-framework.version>5.2.7.RELEASE</spring-framework.version>
    </properties>

    <dependencies>
        <!--spring 核心组件所需依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring-framework.version}</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

</project>

3、新建一个实体类(Bean)类

public class User {
    private String name;

    private String sex;

    private Integer age;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

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

4、Spring配置文件

1、在resources目录下新增一个配置文件,命名建议spring-config.xml或者applicationContext.xml,这就是Spring的核心配置文件。
<?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属性:名字(唯一)-->
    <!--class属性:类的全限定名-->
    <bean id="user" class="com.itan.beans.User"/>
</beans>

5、测试

public class Test1 {
    public static void main(String[] args) {
        // 通过配置文件创建容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        /**
         * 通过容器获取对象,返回的是object类型,可以强转,bean的名称一定要和xml中id属性值对应,
         * 否则报错:org.springframework.beans.factory.NoSuchBeanDefinitionException
         */
        User user = (User) context.getBean("user");
        // 此方法直接返回对应的类型的对象
        User user1 = context.getBean("user", User.class);
        /**
         * 注意:使用这种方式获取bean时,必须保证当前spring的配置文件中,只能有一个<bean/>的class是要获取的类型,
         * 否则报错:org.springframework.beans.factory.NoUniqueBeanDefinitionException
         */
        User user2 = context.getBean(User.class);
        System.out.println(user);
        System.out.println(user1);
        System.out.println(user2);
    }
}
/**
 * 运行结果如下:
 * com.itan.beans.User@57baeedf
 * com.itan.beans.User@57baeedf
 * com.itan.beans.User@57baeedf
 */

三、IoC容器

1、IoC概述

1、Spring的核心机制就是IoC(Inversion of Control),即“控制反转”或“反转控制”,就是将原本在程序中手动创建对象的权力,交由Spring框架来管理,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,在需要的时候进行依赖注入。对象与对象之间松散耦合。
2、交给Spring管理的对象被称为Bean,Bean对象存放的地方被称为IoC容器,或者Bean工厂
3、最直观的意思:IoC让对象的创建不用去new了,可以由Spring自动生产,使用Java的反射机制,根据配置文件在运行时动态的创建对象和管理对象,并调用对象的方法。

2、Spring Bean

1、当配置好需要交给IoC管理的对象,并启动IoC容器,就可以从IoC容器中获取我们需要的对象了;其中,交给IoC容器管理的对象称为Bean,或者说Bean是由IoC容器进行实例化、组装和管理的对象。
2、Spring IoC容器管理一个或多个Bean。这些Bean是用我们提供给容器的配置元数据创建的,配置元数据可以通过以下几种形式来表示:
3、在Spring IoC容器本身中,我们定义的配置元数据创建的Bean对象会转为BeanDefinition对象,BeanDefinition会记录下所有解析到的Bean定义,将解析结果保存起来的好处就是此后就不至于每次用到配置信息的时候都去解析一遍配置元数据。BeanDefinition中包含以下数据:

3、通过XML装配Bean

1、将Bean的信息配置.xml文件里,通过Spring加载文件为我们创建Bean。这种方式出现很多早前的SSM项目中,将第三方类库或者一些配置工具类都以这种方式进行配置,主要原因是由于第三方类不支持Spring注解。
2、优缺点说明:
3、通过<bean />标签在xml文件中配置Bean,常用的属性配置说明如下:
4、上面目录二中的示例代码中就是基于XML装配Bean。

4、通过Java配置装配Bean

1、将类的创建交给我们配置的JavcConfig类来完成,Spring只负责维护和管理,采用纯Java创建方式。其本质上就是把在XML上的配置声明转移到Java配置类中。
2、优缺点说明:
3、实现步骤:
/**
 * @Date: 2022/10/28
 * bean配置类
 */
@Configuration
public class BeanConfig {
    @Bean
    public User user() {
        return new User();
    }
}
public class Test2 {
    public static void main(String[] args) {
        // 通过配置类创建容器对象
        ApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
        /**
         * 获取容器中的bean,name值要与配置中的方法名保持一致,
         * 否则报错:org.springframework.beans.factory.NoSuchBeanDefinitionException
         */
        User user = context.getBean("user", User.class);
        System.out.println(user);
    }
}

5、通过注解装配Bean

1、通过在类上加注解的方式,来声明一个类交给Spring管理,Spring会自动扫描带有@Component,@Controller,@Service,@Repository这四个注解的类,然后帮我们创建并管理,前提是需要先配置Spring的注解扫描器。
2、优缺点说明:
3、实现步骤:
package com.itan.beans;

import org.springframework.stereotype.Component;

/**
 * @Date: 2022/10/23
 */
@Component
public class User {
    private String name;

    private String sex;

    private Integer age;

    public String getName() {
        return name;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}
public class Test3 {
    public static void main(String[] args) {
        // 通过配置类创建容器对象,basePackages配置要扫描的包
        ApplicationContext context = new AnnotationConfigApplicationContext("com.itan.beans");
        // 获取容器中的bean
        User user = context.getBean("user", User.class);
        System.out.println(user);
    }
}

四、依赖注入(DI)

1、概述

1、在实际应用中,Bean对象不可能是单一的,往往一个Bean对象,还会依赖很多其他的Bean的属性。这就有了依赖注入的概念,由DI来维护Bean之间的依赖关系,并且自动注入需要的依赖项,使用DI之后,具有依赖关系的对象之间没有了强耦合关系,对象不需要主动查找、获取其依赖项,甚至都不用知道依赖项的具体位置,它们都在容器中,都交给DI就行。
2、DI(Dependency Injection)即依赖注入,可以说是IoC的其中一个内容,在容器实例化对象的时候主动的将被调用者(或者说它的依赖对象)注入给调用对象。也可以理解为:应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源
3、对象可以通过构造函数参数、工厂方法的参数或从工厂方法构造或返回对象实例后在其上设置属性来定义其依赖(要使用)的其他对象。随后,IoC容器在创建Bean时会自动注入这个Bean的依赖项。这个过程基本上和Bean主动通过类的构造器和setter方法来设置其依赖项的过程是相反的,因此DI也称为控制反转(Inversion of Control、IoC)
4、常用的注入方式主要有三种:
  • 构造方法注入(Construct注入)
  • setter方法注入
  • 基于注解的注入(接口注入)

2、构造方法注入

1、构造器依赖注入是由IoC容器调用带有许多参数的构造器来完成的,每个参数表示一个依赖项。
2、使用构造器依赖注入方式,需要依赖<bean />标签的子标签<constructor-arg />,一个<constructor-arg />标签表示一个属性。
3、<constructor-arg />标签参数介绍:<constructor-arg value="" index="" name="" ref="" type="" />
属性说明
value设置参数列表参数对应的值,用于设定基本数据类型和String类型的数据
index通过参数在参数列表中的索引找到参数列表中对应参数,index从0开始
name通过参数名找到参数列表中对应参数
ref如果参数值为非基本数据类型,则可通过ref为参数注入值,其值为另一个bean标签id或name属性的属性值
type通过参数数据类型找到参数列表中对应参数
public class Subject {
    private String name;

    private String teacher;

    public Subject(String name, String teacher) {
        this.name = name;
        this.teacher = teacher;
        System.out.println("构造器依赖注入");
    }

    @Override
    public String toString() {
        return "Subject{" +
                "科目='" + name + '\'' +
                ", 老师='" + teacher + '\'' +
                '}';
    }
}
<?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">

    <!--Subject类配置-->
    <bean id="subject" class="com.itan.beans.Subject">
        <!--构造函数属性注入,constructor-arg表示一个属性,value表示值-->
        <constructor-arg value="Java" />
        <constructor-arg value="张三" />
    </bean>
</beans>
public class Test4 {
    public static void main(String[] args) {
        // 通过配置文件创建容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 获取bean对象
        Subject bean = context.getBean(Subject.class);
        System.out.println(bean);
    }
}
/**
 * 运行结果:
 * 构造器依赖注入
 * Subject{科目='张三', 老师='Java'}
 */

3、setter方法注入

1、setter依赖注入是由IoC容器调用参数的setter方法完成,setter方法是在调用构造器以实例化bean之后完成的。
2、setter方法实际上就是常说的get、set方法中的set方法,因此在使用setter注入的时候需要提供setXXX方法,这个XXX一般就是表示属性名,方法名应该按照Java方法名的规定来定义,属性的第一个字母大写,通常我们可以使用idea来自动生成set方法。
3、使用setter方法注入方式,需要依赖<bean />标签的子标签<property />,一个<property />标签表示一个setter方法。
4、<property />标签参数介绍:<property name="" value="" ref="" />
属性说明
name属性名称
value设置属性对应的值
ref如果参数值为非基本数据类型,则可通过ref为参数注入值,其值为另一个bean标签id或name属性的属性值
public class Teacher {
    private String name;

    private int age;

    public void setName(String name) {
        System.out.println("setter属性注入name");
        this.name = name;
    }

    public void setAge(int age) {
        System.out.println("setter属性注入age");
        this.age = age;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "姓名='" + name + '\'' +
                ", 年龄=" + age +
                '}';
    }
}
<?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">

    <!--Teacher类配置-->
    <bean id="teacher" class="com.itan.beans.Teacher">
        <!--setter方法属性注入,property表示一个属性,name表示属性名,value表示对应的值-->
        <property name="name" value="张三" />
        <property name="age" value="25" />
    </bean>
</beans>
public class Test4 {
    public static void main(String[] args) {
        // 通过配置文件创建容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 获取bean对象
        Teacher teacher = context.getBean(Teacher.class);
        System.out.println(teacher);
    }
}
/**
 * 运行结果:
 * setter属性注入name
 * setter属性注入age
 * Teacher{姓名='张三', 年龄=25}
 */

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

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

相关文章

从入门到进阶,KingbaseES数据库学习资料整理(持续归档中...)

一、安装和卸载 1.安装包 2.安装&卸载 3.安装、移除组件 4.license 5.安装问题 二、系统管理 1.初始化 2.数据库 3.快速开发管理工具 三、应用开发 1.sql 2.plsql 3.扩展和插件 4.接口 四、迁移 1.初始化和配置 2.迁移数据 3.迁移对象 4.迁移的异常处…

Linux网络原理与编程(2)——第十二节 应用层协议(以HTTP为例)

目录 协议 HTTP协议 认识URL HTTP协议的特征 HTTP的构成及报文格式 报文格式 请求方法 常见的Header 状态码 Cookie 我们从本节开始&#xff0c;就来正式地详细介绍网络各个层次的内容。 我们先从最顶端的应用层协议说起。 在说应用层协议之前&#xff0c;我们来思考…

Day42——Dp专题

文章目录五、多重背包六、背包问题总结动规五部曲背包递推公式遍历顺序18.打家劫舍19.打家劫舍II20.打家劫舍 III&#xff08;dfs缓存/树形DP&#xff09;五、多重背包 对于多重背包&#xff0c;我在力扣上还没发现对应的题目&#xff0c;所以这里就做一下简单介绍&#xff0c…

【SpringMVC】上篇,超详细的教程带你学会SpringMVC

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;【Spring】 &#x1f96d;本文内…

java面向对象----抽象类

目录 抽象类与抽象方法 概念 抽象类应用 接 口 概念 接口的特点&#xff1a; 接口应用举例 Java 8中关于接口的改进 内部类 如何声明局部内部类 局部内部类的特点 匿名内部类 总结 抽象类与抽象方法 概念 随着继承层次中一个个新子类的定义&#xff0c;类变得越…

android OTA update

可以使用系統的API來實現系統更新。分兩種更新&#xff0c;non-streaming 和 streaming。non-streaming就是把更新包下載好&#xff0c;放到本地&#xff0c;然後執行更新。而streaming是爲了你的設備內存不夠&#xff0c;不能把更新包下載下來&#xff0c;使用的&#xff0c;u…

Helm 部署 java 项目到 K8S

文章目录部署流程模板目录文件解析DeploymentServiceIngress_helpers.tplChart.yamlvalues.yaml部署命令部署流程 准备 jar 包使用 Dockerfile 构建镜像上传镜像到仓库&#xff08;Harbor&#xff09;使用 Helm 模板部署 jar 到 K8S 本文着重讲解第四步&#xff0c;如何制作 …

后分库分表时代的数据库新选择:二维火搭载OceanBase再出发

如今&#xff0c;在中国任意走进一家餐饮商户&#xff0c;不论其规模大小&#xff0c;扫码点餐、自助点餐机、商家点餐小程序等已经基本成为标配。随着餐饮行业数智化持续加速推进&#xff0c;餐饮 SaaS 已经逐渐成为商户们的“必选题”&#xff0c;二维火便是这“必选题”之一…

深度解析 Git 是如何工作的?

深度解析 Git 是如何工作的&#xff1f;前言Git 的特性Git 实际上是如何工作的Commits 对象Tree 对象Blobs 对象总结分支创建与合并代码合并与冲突代码合并算法&#xff08;Myers&#xff09;图搜索代码 diff结尾参考&#xff1a;《Pro Git》、《Advanced Git》 前言 Git 是一…

如何实现工具无关化?关于自动化测试脚本的设计

1.问题的提出 最近几年来&#xff0c;我的自动化测试工具之旅大致是这样的&#xff0c;最早用的是QTP,然后是RFT(IBM的功能测试自动化产品),之后也经历了Selenium, Watir等&#xff0c;再后还是一些商业工具主要是偏web自动化及移动自动化&#xff0c;如sahi, appnium, Keynot…

你知道ArcGIS电子地图也有大字体地图吗(附下载方法)

概述 如果你经常使用水经微图&#xff0c;应该知道在水经微图内&#xff0c;百度电子地图和高德电子地图有大字体地图&#xff0c;最近我偶然发现ArcGIS电子地图也有大字体地图&#xff0c;这里给大家介绍一下下载方法。 加载地图 在ArcGIS中打开目录窗格&#xff0c;点击添…

五、卷积神经网络CNN8(不同卷积后图像大小计算)

类型划分 2 维卷积的计算分为了 3 类&#xff1a;1.full 2.same 3. valid 1、full蓝色为原图像&#xff0c;白色为对应卷积所增加的 padding&#xff0c;通常全部为 0&#xff0c;绿色是卷积后图片。图中的卷积的滑动是从卷积核右下角与图片左上角重叠开始进行卷积&#xff…

为什么企业需要实时跟踪进度的项目管理工具?

市场上的大多数 项目管理工具&#xff0c;都是垃圾进-垃圾出&#xff0c;这意味着如果你的团队没有输入正确甚至漏了输入他们活动的状态信息&#xff0c;就无法准确跟踪项目进展。 当选择了一个不能跟踪实时进度状态的项目管理工具&#xff0c;它不能给你提供准确报告进度所需…

大型复杂项目管理之风险预防

最近一个项目让项目经理小王焦头烂额&#xff0c;一问才知是第一次主导大型项目&#xff0c;各个维度的风险问题频发不断&#xff0c;项目感觉推动不下去了。例如&#xff0c;子项目进度延误、项目资源不足、项目交付物质量不过关等因素造成项目的整体延误等等。 项目案例信息&…

GoogLeNet 与 Inception

本篇主要介绍GoogLeNet,其被改进并应用在了YOLOV1目标检测算法中。 GoogLeNet是google推出的基于Inception模块的深度神经网络模型&#xff0c;在2014年的ImageNet竞赛中夺得了冠军&#xff0c;在随后的两年中一直在改进&#xff0c;形成了Inception V2、Inception V3、Incepti…

Java 将PDF转为Word

众所周知&#xff0c;PDF文档除了具有较强稳定性和兼容性外, 还具有较强的安全性&#xff0c;在工作中可以有效避免别人无意中对文档内容进行修改。但与此同时&#xff0c;也妨碍了对文档的正常修改。这时我们可以将PDF转为Word文档进行修改或再编辑。使用软件将 PDF 文档转换为…

Spring事务,浅谈!

目录 一、EnableTransactionManagement工作原理 二、Spring事务基本执行原理 三、Spring事务详细执行流程 四、Spring事务传播机制 五、Spring事务传播机制分类 六、Spring事务强制回滚 七、TransactionSynchronization 一、EnableTransactionManagement工作原理 开启Spr…

在C++中,为什么部分程序员喜欢在循环中写‘++i’而不是‘i++’?

自入行以来&#xff0c;无论是查阅资料、技术博客亦或是同事间的技术交流&#xff0c;都有一个共识:在循环的时候&#xff0c;务必使用前置操作符&#xff0c;因为其性能优于后置操作符&#xff0c;久而久之&#xff0c;这个就像一个不成文的规定&#xff0c;大家都在遵循&…

C++异常介绍

目录 一.异常 1.1C异常概念 1.2异常的使用 1.3异常和栈帧,重新抛出 二.异常体系 2.1自定义异常体系 2.2C标准库的异常体系 2.3异常规范 3.异常的优缺点 3.1优点 3.2缺点 一.异常 1.1C异常概念 语言传统的处理错误的方式&#xff1a; 1. 终止程序&#xff0c;如assert…

浮点类型的比较

浮点类型的比较一.浮点数精度的损失二.浮点数的比较1.方法一2.方法二3.方法三&#xff1a;系统方案一.浮点数精度的损失 关于浮点数的比较就不得不提到浮点数在内存中的存储&#xff0c;但这里篇幅太大&#xff0c;故我将其放在另一篇博客里&#xff0c;&#xff08;如果不了解…