不会使用Spring的配置文件,赶紧把这个甩给他
摘要:文章从Spring程序的快速使用、Bean标签的使用和其属性的具体使用,每个属性都用代码来解释,运行结果和案例也写的都很明白。
本文分享自华为云社区《怎样使用Spring的配置文件?带大家一起玩转Spring配置文件》,作者:我是一棵卷心菜 。
一、Spring程序快速入门
步骤一:导入 Spring 开发的基本包坐标
创建一个maven工程,导入Spring需要的依赖,为了方便测试,我还导入了一个Junit测试包
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.14</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency></dependencies>
步骤二:编写 Dao 接口和实现类
接下里,需要编写一个Dao接口和其实现类,用来搭建测试的环境,话多不说,直接上代码
public interface UserDao {void save();
}
public class UserDaoImpl implements UserDao {@Overridepublic void save() {System.out.println("保存成功~~");}
}
步骤三:创建 Spring 核心配置文件
接口和类写完后,就开始进入正题,在类路径下(resources)创建Spring的核心配置文件,我取名为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">
</beans>
步骤四:在 Spring 配置文件中配置 UserDaoImpl类
创建好xml配置文件后,我要想调用save()方法,就需要创建UserDaoImpl类的对象,这里采用容器的方式。
<bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean>
这里的id是自定义的,最好是类名的首字母小写,方便于记忆。class属性值是要创建类对象的所在包路径,我的这个UserDaoImpl类所在的包路径就是com.sht.dao.impl.UserDaoImpl,这一点都不能写错哦!
步骤五:使用 Spring 的 API 获得 Bean 实例
接下来测试一下:
public class UserDaoDemo {public static void main(String[] args) {ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userdao = (UserDao) applicationContext.getBean("userdao");userdao.save();}
}
通过new ClassPathXmlApplicationContext("applicationContext.xml")获取到容器——applicationContext,然后通过id对应的属性值获取到UserDaoImpl类的对象,这样我们就不需要用new的方式来创建对象了!
以上java代码还可以写成另一种方式:
public class UserDaoDemo {public static void main(String[] args) {ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");UserDaoImpl userDao = applicationContext.getBean(UserDaoImpl.class);userDao.save();}
}
其中,当参数的数据类型是字符串时,表示根据Bean的id从容器中获得Bean实例,返回是Object,需要强转。
当参数的数据类型是Class类型时,表示根据类型从容器中匹配Bean实例,特别注意的是:当容器中相同类型的Bean有多个时,则此方法会报错。
运行结果:
结果正确,到了这里,spring的配置文件你已经有了基本的了解,接下来让我们看看spring配置文件中其它的细节使用吧!
二、Spring配置文件使用
1、Bean标签基本配置
基本介绍
用于配置对象交由Spring 来创建
默认情况下它调用的是类中的无参构造函数,如果没有无参构造函数则不能创建成功,对于有参构造器,后面会慢慢讲到
基本属性
id:Bean实例在Spring容器中的唯一标识
class:Bean的全限定名称
这两个基本属性在快速入门中已经使用过了,就不最多介绍了
Bean标签范围配置(Scope)
修改xml配置文件,在原来的bean中加入scope="singleton",这就意味着,我们不管创建多少个对象,都是同一个
<bean id="userdao" class="com.sht.dao.impl.UserDaoImpl" scope="singleton"></bean>
写一个测试代码
public void test1(){ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userdao1 = (UserDao) context.getBean("userdao");System.out.println(userdao1);UserDao userdao2 = (UserDao) context.getBean("userdao");System.out.println(userdao2);System.out.println("是否为同一个对象实例:" + (userdao1 == userdao2));}
运行结果:
继续修改xml配置文件,把scope="singleton"改为scope="prototype",即表明,我们用其创建对象时,不是同一个对象实例
上面的测试代码不变,运行结果:
Bean标签实例化时机
小伙伴们可能就有疑问了,上面这两种方式是什么时候创建对象实例的呢?不要急,咱们慢慢道来。
为了方便效果的展现,我在UserDaoImpl类的无参构造器中加入一句代码,用来区别创建实例的时机
public UserDaoImpl(){System.out.println("UserDaoImpl开始创建");}
scope为singleton时
运行debug,点击F8
我们可以发现,从加载配置文件的时候就开始创建了对象实例
scope为prototype时
运行debug,按下F8,发现控制台并没有打印“UserDaoImpl开始创建”,说明配置文件并没有加载对象实例
再次按F8下一步
我们可以发现控制台终于打印了“UserDaoImpl开始创建”
总结
当scope的取值为singleton时,当应用加载,创建容器时,对象就被创建了;当scope的取值为prototype时,当使用对象时,才创建新的对象实例。
Bean生命周期配置
在UserDaoImpl类中添加两个方法
public void init(){System.out.println("初始化方法");}public void destory(){System.out.println("销毁方法");}
修改xml配置文件,init-method:指定类中的初始化方法名称,destroy-method:指定类中销毁方法名称
<bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"scope="singleton"init-method="init"destroy-method="destory">
</bean>
编写测试代码
public void test3(){ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userdao1 = (UserDao) context.getBean("userdao");System.out.println(userdao1);UserDao userdao2 = (UserDao) context.getBean("userdao");System.out.println(userdao2);System.out.println("是否为同一个对象实例:" + (userdao1 == userdao2));//这里用来关闭容器((ClassPathXmlApplicationContext) context).close();}
运行结果:
从这个例子,相信大家可以自己推测出创建对象、初始化、方法调用以及销毁的先后顺序了
Bean实例化三种方式
方式一:无参构造方法实例化(重点)
其实我们前面一直使用的就是这一种方法,但是需要注意的是,这种方法会根据默认无参构造方法来创建类对象,如果bean中没有默认无参构造函数,将会创建失败
方式二:工厂静态方法实例化(了解)
创建一个静态工厂类,直接返回UserDaoImpl类的对象实例
public class StaticFactory {public static UserDao getUserDao(){return new UserDaoImpl();}
}
编写xml配置文件的bean,这里的class属性值是静态工厂类对应的包的路径,factory-method对应的属性值是类中的方法名
<bean id="userdao" class="com.sht.factory.StaticFactory" factory-method="getUserDao"></bean>
编写代码测试
public class UserDaoDemo {public static void main(String[] args) {ApplicationContext applicationContext =new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userdao = (UserDao) applicationContext.getBean("userdao");userdao.save();}
}
最终的运行结果还会是:“保存成功~~”
方式三:工厂实例方法实例化(了解)
创建一个工厂类,同样返回UserDaoImpl类的对象实例
public class DynamicFactory {public UserDao getUserDao(){return new UserDaoImpl();}
}
编写xml配置文件的bean,这里的class属性值是工厂类对应的包的路径,第一个bean可以得到工厂类的对象,再写一个bean,用来获取UserDaoImpl类的对象实例。factory-bean属性值代表从哪个工厂里面拿,factory-method对应的属性值是类中的方法名
<bean id="factory" class="com.sht.factory.DynamicFactory"></bean>
<bean id="userdao" factory-bean="factory" factory-method="getUserDao"></bean>
最终的运行结果也是:“保存成功~~”
总结
2、Bean的依赖注入
基本介绍
依赖注入(Dependency Injection):它是 Spring 框架核心 IOC 的具体实现。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。IOC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。
简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
Bean的依赖注入方式
方式一:有参构造方法
前面讲的都是无参构造方法,现在讲讲有参构造方法。我们先创建一个UserService接口和其实现类UserServiceImpl
public interface UserService {void save();
}
public class UserServiceImpl implements UserService {private UserDao userdao;public UserServiceImpl(UserDao userdao) {this.userdao = userdao;}@Overridepublic void save() {userdao.save();}
}
编写xml配置文件的bean,class属性值分别对应类下的包路径。<constructor-arg name="userdao" ref="userdao"></constructor-arg>中name属性值是相应set方法名的去掉set后的首字母小写,ref是引入引入数据类型,即表示着对象属性的注入
<bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean><bean id="userService" class="com.sht.service.impl.UserServiceImpl"><constructor-arg name="userdao" ref="userdao"></constructor-arg></bean>
方式二:set方法
接口不变,改变一下UserServiceImpl 类,需要注意的是,setUserdao()的权限是public,不能写成private哦
public class UserServiceImpl implements UserService {private UserDao userdao;//权限是publicpublic void setUserdao(UserDao userdao){this.userdao = userdao;}@Overridepublic void save() {userdao.save();}
}
编写xml配置文件的bean,class属性我就不再说明了。重点讲解的是<property name="userdao" ref="userdao"></property>;name属性值是相应set方法名的去掉set后的首字母小写,ref是引入引入数据类型,即表示着对象属性的注入;这里把UserDaoImpl类的对象注入到UserServiceImpl类中,就可以调用其save()方法了
<bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean><bean id="userService" class="com.sht.service.impl.UserServiceImpl"><property name="userdao" ref="userdao"></property></bean>
测试代码:
public void test5(){ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");UserService userService = (UserService) context.getBean("userService");userService.save();}
运行结果:
此外,set方法中有一个特殊的方法:P命名空间注入。其本质也是set方法注入,但比起上述的set方法注入更加方便,主要体现在配置文件中,如下:
引入xmlns:p="http://www.springframework.org/schema/p"名称空间,其次p:userdao-ref属性值是跟ref对应的属性值的含义是一样的,这种方法可以作为了解
<?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:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean> <bean id="userService" class="com.sht.service.impl.UserServiceImpl" p:userdao-ref="userdao"></bean>
</beans>
3、Bean的依赖注入数据类型
普通数据类型的注入
我用set方法的方式,讲解bean的依赖注入。继续在UserDaoImpl类中添加两个基本数据类型和它们的set方法
private String name;private Integer age;public void setName(String name) {this.name = name;}public void setAge(Integer age) {this.age = age;}public void show() {System.out.println("名字是" + name + "的年龄是" + age);}
修改xml配置文件的bean,name的属性值代表着set方法的名,value的属性值表示你想要填入的属性值
<bean id="userDao" class="com.sht.dao.impl.UserDaoImpl"><property name="name" value="卷心菜"></property><property name="age" value="20"></property>
</bean>
写一个测试类:
public void test7(){ApplicationContext context =new ClassPathXmlApplicationContext("applicationContext.xml");UserDaoImpl contextBean = context.getBean(UserDaoImpl.class);contextBean.show();}
运行结果:
集合数据类型的注入
List<String>类型的注入
继续在UserDaoImpl类中改动代码:private List<String> stringList;public void setStringList(List<String> stringList) {this.stringList = stringList;}public void showStringList() {System.out.println(stringList);}
修改xml配置文件,注入基本数据类型就是两个关键字<list>和<value>
<bean id="userDao" class="com.sht.dao.impl.UserDaoImpl"><property name="stringList"><list><value>111</value><value>222</value><value>333</value></list></property></bean>
运行结果:
List<User>类型的注入
先创建一个User类,有对应的get和set方法,还有toString方法,方便测试使用
public class User {private Integer id;private String username;private String password;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +'}';}
}
修改xml配置文件的bean,可以看出,与之前不同的是,<list>中用的是<ref>标签,这个标签表示的是注入引用数据类型
<bean id="user01" class="com.sht.domain.User"><property name="id" value="1"></property><property name="username" value="卷心菜"></property><property name="password" value="123456"></property></bean><bean id="user02" class="com.sht.domain.User"></bean><bean id="userDao" class="com.sht.dao.impl.UserDaoImpl"><property name="userList"><list><ref bean="user01"></ref><ref bean="user02"></ref></list></property></bean>
运行结果:
Map<String,User> 类型的注入
继续在UserDaoImpl类中改动代码:
private Map<String, User> stringUserMap;public void setStringUserMap(Map<String, User> stringUserMap) {this.stringUserMap = stringUserMap;}public void showStringUserMap() {System.out.println(stringUserMap);}
修改xml配置文件,与之前不同的是,当使用的是map时,标签用的是<map>和标签<entry>,使用方法跟list标签差不多
<bean id="user01" class="com.sht.domain.User"><property name="id" value="1"></property><property name="username" value="卷心菜"></property><property name="password" value="123456"></property></bean><bean id="userDao" class="com.sht.dao.impl.UserDaoImpl"><property name="stringUserMap"><map><entry key="key1" value-ref="user01"></entry></map></property></bean>
运行结果:
需要注意的是,我们在选择key属性时,会有一个如图所示的key-ref的提示,这代表着我们要用的key是一个引入数据类型,因为我用的key是String,所以选择key
当使用value-ref时,也会出现value的值,其用法跟上面一样
Properties类型的注入
继续在UserDaoImpl类中改动代码:
private Properties properties;public void setProperties(Properties properties) {this.properties = properties;}public void showProperties(){System.out.println(properties);}
修改xml配置文件,与之前的不同之处就是标签使用的是<props>和标签<prop>,使用的方法也是跟上面的方法类似
<bean id="userDao" class="com.sht.dao.impl.UserDaoImpl"><property name="properties"><props><prop key="key01">value1</prop><prop key="key02">value2</prop></props></property></bean>
运行结果:
4、引入其他配置文件(分模块开发)
创建一个新的配置文件applicationContext1.xml,实际开发中,Spring的配置内容非常多,这就导致Spring配置很繁杂且体积很大,所以,可以将部分配置拆解到其他配置文件中,而在Spring主配置文件通过import标签进行加载
把applicationContext1.xml配置文件中的配置内容引入到applicationContext.xml的实现方式:
<import resource="applicationContext1.xml"></import>
总结
以上就是Spring配置文件的相关知识点,带大家来看看Spring的重点配置:
点击关注,第一时间了解华为云新鲜技术~
不会使用Spring的配置文件,赶紧把这个甩给他相关推荐
- Spring Boot配置文件学习记录【1】
[1]Spring Boot配置文件 Spring Boot配置层面的知识已学习完.总结一下本周的学习内容,一切都需要从@SpringBootApplication谈起,因为它,做到了真正配置文件的简 ...
- Spring读取配置文件,获取bean的几种方式
Spring读取配置文件,获取bean的几种方式 方法一:在初始化时保存ApplicationContext对象 代码: ApplicationContext ac = new FileSystemX ...
- applicationcontext添加配置_Spring源码分析2 — spring XML配置文件的解析流程
1 介绍 创建并初始化spring容器中,关键一步就是读取并解析spring XML配置文件.这个过程比较复杂,本文将详细分析整个流程.先看涉及到的关键类. XmlWebApplicationCont ...
- Spring Boot配置文件放在jar外部
Spring Boot配置文件放在jar外部 2018年03月16日 10:09:17 qq_37334435 阅读数:1488 Spring Boot程序默认从application.propert ...
- Spring Boot 配置文件详解
2019独角兽企业重金招聘Python工程师标准>>> 第二篇 : Spring Boot配置文件详解 文章首发于微信公众号<程序员果果> 地址:https://mp.w ...
- spring 获取配置文件的值
Spring 获取配置文件的值 package com.hafiz.www.util;import org.slf4j.Logger; import org.slf4j.LoggerFactory;i ...
- Spring Boot 配置文件的加载优先级
1. 前言 今天突发奇想,如果Spring Boot的配置文件同时存在application.properties和application.yaml,于是便测试了一波.结果测出来优先级的顺序为 pro ...
- spring 读取配置文件的优先级
为什么80%的码农都做不了架构师?>>> spring 读取配置文件的优先级 1 结论 在spring加载properties配置文件的过程中,会根据key出现覆盖现象,后加载 ...
- Spring第三讲:利用注解配置类取代Spring的配置文件
一.上次学习的内容 上次的学习了利用组注解符精简Spring配置文件 二.今天要学习的内容 (1)利用注解配置类取代Spring的配置文件 三.实现步骤 (一)运行测试我们上次做的项目的代码是否完整, ...
最新文章
- 核磁共振影像数据处理-1(下)-DWI基础、Li‘s have a solution and plan.
- 04:网络层协议介绍
- GIT服务器搭建(转载)
- parallels desktop虚拟机与Mac共享网络设置方法
- Log4net系统日志
- navigation笔记
- module.exports 和 exports 的区别
- 无聊的小知识--数据中心为啥要建在山区
- python中文件分类_利用Python将文件进行分类整理
- verilog简单驱动VGA
- android测试篇(三)单元测试之UI测试 Espresso学习与实践
- OpenCV读取海康4G摄像头
- ble学习笔记九----------ble协议栈之OSAL的运行机理
- 2022年快手电商“大搞产业带”,如何抢跑快手电商下半场?
- 客户心声 | 四川省人社厅杨玉成一行充分肯定桂溪街道劳动保障工作信息化建设平台
- 英语音标,元音汇总(0基础学英语!必备!)
- MySQL理论基础以及sql语法
- 知乎首页实战之背景与大体布局
- centos7防火墙端口设置
- 平行世界真的存在吗?镜像宇宙的三个科学奥秘