Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >2-Spring配置文件与依赖注入

2-Spring配置文件与依赖注入

作者头像
Ywrby
发布于 2022-10-27 05:30:58
发布于 2022-10-27 05:30:58
26800
代码可运行
举报
文章被收录于专栏:YwrbyYwrby
运行总次数:0
代码可运行

Spring配置文件

Bean标签基本配置

用于配置对象交由Spring来创建,默认情况下调用的是类中的无参构造函数,没有无参构造的情况下不能创建成功

基本属性
  • id:Bean实例在Spring中的唯一标识
  • class:Bean的全限定名称

Bean标签范围配置

scope属性

取值范围

说明

singleton

默认值,单例的

prototype

多例的

request

web项目中,Spring创建一个对象并将对象存入request域内

session

web项目中,Spring创建一个对象并将对象存入session域内

global session

web项目中,应用在Portlet环境,如果没有Portlet环境,global session相当于session

这里单例是指每次创建出的Bean对象都是同一个对象,而多例则表示每次创建的都是全新的不同的Bean对象

示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!--单例的-->
<bean id="userDao" class="cn.ywrby.dao.impl.UserDaoImpl" scope="singleton"></bean>
<!--多例的-->
<bean id="userDao" class="cn.ywrby.dao.impl.UserDaoImpl" scope="prototype"></bean>

测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 测试scope属性
 */
@Test
public void userDaoTest(){
    //指定配置文件
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    //通关配置文件与ID获取实例
    UserDao dao1= (UserDao) context.getBean("userDao");
    UserDao dao2= (UserDao) context.getBean("userDao");
    //输出两个对象的地址即可判断是否两次创建为同一对象
    System.out.println(dao1);
    System.out.println(dao2);
}
singleton与prototype的区别

当scope取值为singleton时,Bean实例化的个数始终是一个,并且实例化的时机是在Spring核心文件(配置文件)被加载时

当scope取值为prototype时,Bean实例化的个数是多个,此时实例化的时机不是核心文件加载,而是在每次调用getBean方法时创建

Bean声明周期的配置

  • init-method:指定初始化方法,在对象创建时被调用
  • destroy-method:指定销毁方法,在对象被销毁时调用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="userDao" class="cn.ywrby.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserDaoImpl implements UserDao {

    public void init(){
        System.out.println("执行初始化...");
    }

    public void destroy(){
        System.out.println("执行销毁...");
    }

    public void save() {
        System.out.println("Save Running...");
    }
}

Spring依赖注入

概念

依赖注入(Dependency Injection)是Spring框架核心IOC的具体实现

Bean对象的注入(引用数据类型的注入)

依赖注入的主要目的还是解耦,主要利用的原理就是控制反转,即将构造对象这个【控制】交给了第三方Spring来进行操作

我们在实际的项目开发中,必然涉及到对多个对象的构造与控制,而我们许多的对象已经预定义在Spring容器中(那些已经在配置文件中定义的对象)。

此时假如我们需要在某个Spring容器中已有的对象A内调用另一个同样已经在Spring容器中定义的对象B,一般情况我们会直接在对象A中加载配置文件,利用Spring获取对象B,然后再操作获取到的对象

这种情况下假如我们需要修改代码,就需要到所有操作配置文件获取对象B的方法内进行修改,直接导致了代码耦合度变高

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserServiceImpl implements UserService {
    @Override
    public void save() {
        //UserService与UserDao都是定义在Spring容器中的对象
        //这里在UserService的save方法中利用配置文件获取了UserDao对象
        //这也就导致了代码耦合度很高,不便于复用和修改
        ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao dao= (UserDao) context.getBean("userDao");
        dao.save();
    }
}

要解决这种问题就可以利用依赖注入,第一种方式是set方法注入,第二种是构造函数注入

set方法注入

即通过在配置文件中提前配置,使得在创建对象A时调用指定的set方法将对象B直接传入对象A内部,这样的注入方式保证了对象B没有在对象A的方法中进行实例化,而是作为参数直接传入A内部,需要使用对象B时直接使用传入的对象即可。需要修改代码时只需要对配置文件进行修改即可

首先在被传入的Bean中定义传入参数的set方法,并且定义成员变量用于接收传入的参数,修改调用对象B的函数,直接利用成员变量进行操作即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserServiceImpl implements UserService {
    private UserDao dao;  //定义成员变量

    //定义set方法,用于其他对象的传入
    public void setDao(UserDao dao) {
        this.dao = dao;
    }

    @Override
    public void save() {
        //修改成员方法,可以直接利用成员变量进行操作
        //省去了对配置文件的使用,降低了代码耦合度
        dao.save();
    }
}

然后修改配置文件,指定在创建UserService时调用指定的set方法注入相关参数(利用property标签进行指定 其中name是set方法后面的后缀并首字母小写,例如setDao方法,这里就传入dao,setUserService方法就传入userService ,ref是要传入的Spring容器中对象的ID)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="userDao" class="cn.ywrby.dao.impl.UserDaoImpl" ></bean>
<bean id="userService" class="cn.ywrby.service.impl.UserServiceImpl" >
    <property name="dao" ref="userDao"></property>
</bean>

测试用例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * 测试依赖注入
 */
@Test
public void userServiceTest(){
    //指定配置文件
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    //通关配置文件与ID获取实例
    UserService service= (UserService) context.getBean("userService");
    //执行方法
    service.save();
}

P命名空间注入

这种注入方式本质还是set方法注入,只是通过利用P命名空间,简化了配置方法

在配置时首先需要定义P命名空间(第三行即定义P命名空间)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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">

利用P命名空间的属性直接定义注入方法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="userService" class="cn.ywrby.service.impl.UserServiceImpl" p:dao-ref="userDao"></bean>
构造函数注入

构造函数注入就是在创建对象A时调用对象A的有参构造函数,将指定的对象B作为参数注入对象A中

首先需要在被注入的对象中创建有参构造

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserServiceImpl implements UserService {
    private UserDao dao;  //定义成员变量

    //定义有参构造
    public UserServiceImpl(UserDao dao) {
        this.dao = dao;
    }

    public UserServiceImpl(){}

    @Override
    public void save() {
        //修改成员方法,可以直接利用成员变量进行操作
        //省去了对配置文件的使用,降低了代码耦合度
        dao.save();
    }
}

然后在配置文件中声明要调用有参构造,并指定传入的对象在Spring容器中的ID(利用constructor-arg标签指定要传入的参数,name属性表示的是传入的对象命名,ref属性是传入参数在Spring容器中的ID)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="userDao" class="cn.ywrby.dao.impl.UserDaoImpl" ></bean>
<bean id="userService" class="cn.ywrby.service.impl.UserServiceImpl" >
    <constructor-arg name="dao" ref="userDao"></constructor-arg>
</bean>

普通数据类型的注入

在使用中,我们除了可能注入Spring中已经定义的引用数据类型,也有可能需要注入普通类型数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserDaoImpl implements UserDao {

    //定义普通数据类型的成员变量
    private int num;
    private String name;

    //定义set方法
    public void setNum(int num) {
        this.num = num;
    }

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

    public void save() {
        System.out.println(name+" : "+num);
    }
}

修改配置文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<bean id="userDao" class="cn.ywrby.dao.impl.UserDaoImpl" >
    <property name="name" value="Leslie"/>
    <property name="num" value="18"/>
</bean>

因为此时注入的是普通数据类型,所以不需要通过ref属性指定ID,此时直接通过value属性将要注入的值传入

集合数据类型的注入

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class UserDaoImpl implements UserDao {

    //定义集合数据类型
    private List<String> nameList;
    private Map<String, User> userMap;
    private Properties properties;

    //定义set方法
    public void setNameList(List<String> nameList) {
        this.nameList = nameList;
    }

    public void setUserMap(Map<String, User> userMap) {
        this.userMap = userMap;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public void save() {
        System.out.println(nameList);
        System.out.println(userMap);
        System.out.println(properties);
    }
}

以下是集合数据类型注入时配置文件的配置方式

可以看到List类型注入时只需要定义value标签即可,标签体内传注入的值

Map类型在注入时需要利用entry标签传入键和值,键和值都可以使用引用类型或普通类型,引用类型只需要在后面加“-ref”即可

properties类型注入时和Map类似,也需要传入键和值,但是键是通过key属性传入的,值是直接写在标签体中的

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?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="userDao" class="cn.ywrby.dao.impl.UserDaoImpl" >
        <property name="nameList">
            <list>
                <value>Leslie</value>
                <value>Ywrby</value>
            </list>
        </property>
        <property name="userMap">
            <map>
                <entry key="1" value-ref="user1"></entry>
                <entry key="2" value-ref="user2"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="p1">value1</prop>
                <prop key="p2">value2</prop>
            </props>
        </property>
    </bean>
    
    <bean id="user1" class="cn.ywrby.domain.User">
        <property name="name" value="Jessica"></property>
        <property name="addr" value="Peking"></property>
    </bean>
    
    <bean id="user2" class="cn.ywrby.domain.User">
        <property name="name" value="Lere"></property>
        <property name="addr" value="SJZ"></property>
    </bean>
    
    <bean id="userService" class="cn.ywrby.service.impl.UserServiceImpl" >
        <constructor-arg name="dao" ref="userDao"></constructor-arg>
    </bean>
</beans>

测试用例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
public void userDaoTest3(){
    //指定配置文件
    ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
    //通关配置文件与ID获取实例
    UserDao dao= (UserDao) context.getBean("userDao");
    //执行方法
    dao.save();
}
/*
运行结果:
[Leslie, Ywrby]
{1=User{name='Jessica', addr='Peking'}, 2=User{name='Lere', addr='SJZ'}}
{p1=value1, p2=value2}
 */

其他配置文件的引入

实际开发过程中我们所需要的配置文件可能是十分巨大的,内容十分杂乱,如果都定义在一个配置文件中,可读性和复写性都大打折扣

这种情况下我们可以将配置文件进行按模块拆分,或其他方式进行拆分,只需要最后在主配置文件中利用import标签进行引入即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<import resource="applicationContext-user.xml"/>
<import resource="applicationContext-userDao.xml"/>
<import resource="applicationContext-userService.xml"/>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
怎样使用Spring的配置文件?带大家一起玩转Spring配置文件
创建一个maven工程,导入Spring需要的依赖,为了方便测试,我还导入了一个Junit测试包
我是一棵卷心菜
2022/01/18
1.4K0
Spring依赖注入详解
P命名空间注入本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
兮动人
2021/10/15
2.6K0
Spring依赖注入详解
Spring 简介和配置
通过xml文件配置bean,随着项目的不断扩大,需要将xml配置分放到不同的配置文件中,需要频繁的在java类和xml配置文件中切换。
繁依Fanyi
2023/05/07
1640
Spring 简介和配置
Spring从入门到精通(七)—Bean标签详解
用于配置对象交由Spring 来创建。 默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功。
共饮一杯无
2022/11/28
2780
Spring之DI依赖注入
​ name:对应bean中的属性名,要求该属性必须提供可访问的set方法(严格规范为此名称是set方法对应名称)
楠羽
2022/11/18
5220
Spring之DI依赖注入
4-注解开发与Junit集成
Spring是轻代码而重配置的框架,一般情况下,配置比较繁重,影响开发效率,所以注解开发是一种必然趋势,注解代替XML配置文件可以简化配置,提高开发效率
Ywrby
2022/10/27
2450
Spring【依赖注入】就是这么简单
前言 在Spring的第二篇中主要讲解了Spring Core模块的使用IOC容器创建对象的问题,Spring Core模块主要是解决对象的创建和对象之间的依赖关系,因此本博文主要讲解如何使用IOC容器来解决对象之间的依赖关系! 回顾以前对象依赖 我们来看一下我们以前关于对象依赖,是怎么的历程 直接new对象 在最开始,我们是直接new对象给serice的userDao属性赋值… class UserService{ UserDao userDao = new UserDao(); } 写DaoF
Java3y
2018/03/15
8400
Spring【依赖注入】就是这么简单
Spring--框架学习
为了后期方便各州测试,在/src下新建test测试目录,在其中新建java文件夹,里面写测试代码
花猪
2022/02/22
1.3K0
Spring--框架学习
学习Spring框架这一篇就够了
Spring是分层的 Java SE/EE应用 full-stack(全栈的) 轻量级开源框架,以 IOC(Inverse Of Control:控制反转)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。
全栈程序员站长
2022/09/07
1.6K0
学习Spring框架这一篇就够了
Spring:IOC 控制反转
Spring 是分层的 Java SE/EE 应用 full-stack (全栈式) 轻量级开源框架。
RendaZhang
2020/09/16
9800
Spring:IOC 控制反转
Spring概述
2006年10月,发布 Spring2.0 2009年12月,发布 Spring3.0 2013年12月,发布 Spring4.0 2017年9月, 发布最新 Spring5.0 通用版(GA)
张哥编程
2024/12/13
1720
spring——依赖注入
依赖注入的概念 DI的全称是Dependency Injection,中文称之为依赖注入。它与控制反转(IoC)的含义相同,只不过这两个称呼是从两个角度描述的同一个概念。 IOC:在使用Spring框架之后,对象的实例不再由调用者来创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。这样,控制权由应用代码转移到了Spring容器,控制权发生了反转,这就是控制反转。 DI:从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成
兮动人
2021/06/11
7210
spring——依赖注入
JAVAEE框架整合技术之Spring01-IOC教程
2006年10月,发布 Spring2.0 2009年12月,发布 Spring3.0 2013年12月,发布 Spring4.0 2017年9月, 发布最新 Spring5.0 通用版(GA)
张哥编程
2024/12/13
1480
JAVAEE框架整合技术之Spring01-IOC教程
Spring: (一) -- 春雨润物之 核心IOC
作为一个Java人,想必都或多或少的了解过Spring。对于其优势也能道个一二,诸如方便解耦、支持AOP编程、支持声明式事务、方便测试等等。Spring也不仅仅局限于服务器端开发,它可以做非常多的事情,任何Java应用都可以在简单性、可测试性和松耦合等方面从Spring中受益。Spring丰富功能的底层都依赖于它的两个核心特性:
宋先生
2019/07/18
6590
【SSM_01】Spring-IOC
一、spring 概述 1. 什么是 spring * spring 是分层的 java ee 应用,全栈(full-stact)轻量级开源框架,主要有 IOC(反转控制) 、 AOP(面向切面编程) * 反转控制:将对象的创建全交给 spring,有利于解耦,降低代码的依赖关系 2. 使用方法 ① 导包 需要导入 4 个jar包 【spring-aop 、spring-beans 、spring-core 、spring-expression】 导入 spring-context 相当
用户8250147
2021/02/04
2200
java之spring之scope和autowiring
一. scope: 域 ; 在spring中由容器创建对象时可以以指定其scope,那么容器会根据不同的scope的值,创建指定域的对象。
Vincent-yuan
2019/09/11
3720
java之spring之scope和autowiring
java Spring系列之 配置文件的操作 +Bean的生命周期+不同数据类型的注入简析+注入的原理详解+配置文件中不同标签体的使用方式
写在文章前面: 本文带大家掌握Spring配置文件的基础操作以及带领大家理清依赖注入的概念,本文涉及内容广泛,如果各位读者耐心看完,应该会对自身有一个提升
一只胡说八道的猴子
2020/09/27
2K0
java Spring系列之 配置文件的操作 +Bean的生命周期+不同数据类型的注入简析+注入的原理详解+配置文件中不同标签体的使用方式
SpringIOC
IOC:控制反转的底层原理就是:工厂模式+反射+配置文件 DI:依赖注入就是通过配置文件设置属性值
用户3112896
2019/09/26
4030
Spring框架入门笔记
IoC(Inverse Of Control:反转控制)通过配置的方式,将对象的管理控制权交给spring容器,spring得到具体的包路径,类路径通过反射的方式,创建对象。
咕咕星
2020/12/15
3150
Spring框架入门笔记
Spring框架的秘密
spring(春天),生于在2002年,由Rod Johnson创作。Spring框架是一个集众多设计模式于一身的开源的、轻量级的项目管理框架。致力于JAVAEE轻量级解决方案。相对于原来学过的框架而言,spring框架和之前学习的struts2 、 mybatis 框架有了本质的区别,不是替换原来的某个框架,而是对其进行整合管理。
猫头虎
2024/04/07
1300
Spring框架的秘密
相关推荐
怎样使用Spring的配置文件?带大家一起玩转Spring配置文件
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验