Spring Boot 第二d,配置文件详解-史上最全

Spring Boot 第二d,配置文件详解-史上最全,第1张

  Spring Boot 官方 提供了两种常用的配置文件格式,分别是 properties 、 YML 格式。相比于 properties 来说, YML 更加年轻,层级也是更加分明。 强烈推荐使用 YML 格式

  Spring Boot项目 启动会扫描以下位置的 application.properties 或者 application.yml 作为默认的配置文件.

徒手撕源码

内部类Loader的load方法

getSearchLocations()方法

asResolvedSet()

下面给出优先级 从高到低 的配置文件排列顺序:

以设置应用端口为例 初体验Spring Boot配置文件

properties后缀结尾(application.properties)

yml/yaml后缀结尾(application.yml/application.yaml)

数字,字符串,布尔,日期

对象、Map

数组

数字,字符串,布尔,日期

对象、Map

数组

@ConfigurationProperties(prefix = "person")详解

标注在类上

标注在方法上

综上所述

  @ConfigurationProperties 注解能够轻松的让配置文件跟实体类绑定在一起。

 值得关注的是: @ConfigurationProperties 这个注解仅仅是支持从 Spring Boot的默认配置文件 中取值,也就是 application.properties 、 application.yml 、 application.yaml ,那我们如何从自定义配置文件取值呢???

 别着急,有解决办法,那就是再加一个注解: @PropertySource(value = "classpath:custom-profile.properties") ,下面会有对 @PropertySource 注解的介绍。请耐心往下面看。

使用@PropertySource注解

对应配置文件

创建两个配置文件 custom-profile.yml、custom-profile1.yml ,如下去引入。

我们可以通过控制变量法进行测试,具体过程我这里就不赘述了。

直接说 结论 吧: Spring加载顺序 为 从左到右顺序加载 ,后加载的会 覆盖 先加载的属性值。

另外需要注意的是 : @PropertySource 默认加载 xxx.properties类型 的配置文件,不能加载 YML格式 的配置文件。如何解决呢?下面来解决这一问题

对应配置文件:

编写PropertiesController

扩展功能

application.yml 主配置文件

application-dev.yml 开发配置文件

application-prod.yml 生产配置文件

application-test.yml 测试配置文件

(1)主配置文件:配置激活选项

(2)其他配置文件:指定属于哪个环境(同yml,只不过表现形式是 key=value 的,三个配置文件分别是: application-dev.properties , application-prod.properties , application-test.properties )

 无论是使用上述 多文档块 的方式,还是新建 application-test.yml 文件,都可以在配置文件中指定 spring.profiles.active=test 激活指定的profile。

感谢阅读小生文章。祝大家早日富可敌国,实现财富自由。

写文不易 ,一定要 点赞、评论、收藏哦 , 感谢感谢感谢!!!

在spring的xml配置文件中,在头部会出现如下的东西

这些奇怪的xmlns和很长的url的作用是什么呢?

首先,介绍一下 xmlns 的作用,如下所示,一个 xml 文档中如果包含如下两种定义不同, 但是名称相同的元素, xml 解析器是无法解析的, 因为它不能确定当你调用document.getElementsByTagName("book") 时应该返回哪个元素。

这时候可以通过在名称增加前缀解决这个问题

由此,引入一个概念 命名空间 ,通过增加前缀表示不同的那是不同命名空间下的table,从而解决了矛盾,但是不同的人都有自己创建的不同的命名空间来描述同样的东西,不利于xml文件信息的解析,比如说,同样都是水果,可以从颜色和香味不同角度来定义成如下两种形式:

为此,w3c(万维网联盟)对于一些类型,定义了对应的命名空间和这些类型的标准,xml解释器碰到这些类型的时候就会通过这些标准去解析这类型的标签,为了确保命名空间的唯一,所以不同的命名空间的通常使用URL作为被识别的id,如下例子:

这句话的作用是当前引入了一个叫做xsi的命名空间,xsi可以在接下来要使用该命名空间时所使用的,如下:

而 http://www.w3.org/2001/XMLSchema-instance 这个很长的字符串,则是xsi这个名称空间被xml解释器内部所识别的时候所真正使用的id,但也本身只是被当做一个字符串名字去处理,xml解释器根据这个id去获取它对应的标准,从而知道这个命名空间定义有什么样的标签(xml解释器自带有一些通用的命名空间的标准),这个字符串虽然看起来是URL,但是和对应的网页上的信息没有关系,只是用来提供命名空间 唯一性 的作用,网址有时可以被打开,上面会有关于该命名空间的信息。

所以,spring配置文件中这三句话分别表示,引入了三个命名空间。

其中第一个xmlns后面没有空间名的,表示引入了一个默认的名称空间,下文中不使用命名空间前缀的都默认使用这个命名空间,这个默认的命名空间,其真正的id是 " http://www.springframework.org/schema/beans "

引入的第二个命名空间叫做xsi,其真正的id是 " http://www.w3.org/2001/XMLSchema-instance "

引入的第三个命名空间叫做context,其真正的id是 " http://www.springframework.org/schema/context "

在最后可以看到xsi:schemaLocation,这句话的意思表示使用命名空间xsi下的schemaLocatioin,设置了它对应的值为后面很多很多的URL,schemaLocation中存储的值每两个为一组, 第一个代表命名空间,第二个代表该命名空间的标准的文件位置 ,如下所示,这句话就是说明命名空间 http://www.springframework.org/schema/beans 的标准文件是 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd *

因为xml解释器不一定含有所有命名空间的标准,通过这样设置就可以告诉xml解释器不同命名空间的对应的标准是什么了,而这也是xsi这个命名空间的作用,要用到其schemaLocation。

最后,对应一般的xml解释器的工作流程中,xml解释器识别到有 “ http://www.w3.org/2001/XMLSchema-instance " 这个通用的名称空间后,明白知道要引入一些不同命名空间,就会从其schemaLocation中获取不同命名空间和其对应的标准。

传统的创建对象的方法是直接通过 new 关键字 ,而 spring 则是通过 IOC 容器来创建对象,也就是说我们将创建对象的控制权交给了 IOC 容器。我们可以用一句话来概括 IOC

Spring 容器创建对象的三种方式

传统的创建对象的方法:new 关键字

这里通过 Spring 容器怎么来创建呢?

第一种方法:利用默认的构造方法

在 src 目录下新建 applicationContext.xml 文件,这是 spring 配置文件,添加如下代码:

<?xml version="1.0" encoding="UTF-8"?>

<beans p=""

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:唯一标识符

class:类的全类名

-->

/**

* Spring 容器利用构造函数创建对象

*/

@Test

public void testCreateObjectByConstrutor(){

//1、启动 spring 容器

ApplicationContext context =

new ClassPathXmlApplicationContext("applicationContext.xml")

//2、从 spring 容器中取出数据

HelloIoc IOC = (HelloIoc) context.getBean("helloIoc")

//3、通过对象调用方法

IOC.sayHello()

//利用配置文件 alias 别名属性创建对象

HelloIoc IOC2 = (HelloIoc) context.getBean("helloIoc2")

IOC2.sayHello()

}

HelloIoc.java 中手动添加无参的构造方法,然后执行上面的测试代码,会发现构造方法会在 sayHello()方法执行之前调用

<?xml version="1.0" encoding="UTF-8"?>

<beans p=""

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">

public static void main(String[] args) {

ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml")

JavaWork javaWork=(JavaWork)ac.getBean("javaWork")

javaWork.doTest()

}

public class JavaWork {

private Tester tester

public void setTester(Tester tester) {

this.tester = tester

}

public void doTest(){

/*ZhangSan zhangsan=new ZhangSan()

zhangsan.test()*/

tester.test()

}

}

第二种方法:利用静态工厂方法

首先创建静态工厂类 HelloStaticFactory.java

接着在 applicationContext.xml 中进行如下配置:

<!--

创建对象的第二种方式:利用静态工厂方法

factory-method:静态工厂类的获取对象的静态方法

class:静态工厂类的全类名

-->

/**

* Spring 容器利用静态工厂方法创建对象

*/

@Test

public void createObjectStaticFactory(){

ApplicationContext context =

new ClassPathXmlApplicationContext("applicationContext.xml")

HelloIoc staticFactory =

(HelloIoc) context.getBean("helloStaticFactory")

staticFactory.sayHello()

}

spring容器只负责调用静态工厂方法,而这个静态工厂方法内部实现由程序员完成

利用实例工厂方法

首先创建实例工厂类 HelloInstanceFactory .java

public class HelloInstanceFactory {

public HelloInstanceFactory(){

System.out.println("实例工厂方法构造函数")

}

//利用实例工厂方法创建对象

public HelloIoc getInstance(){

HelloIoc instanceIoc = new HelloIoc()

return instanceIoc

}

}

接着在 applicationContext.xml 中进行如下配置:

<!--

创建对象的第三种方式:利用实例工厂方法

factory-bean:指定当前Spring中包含工厂方法的beanID

factory-method:工厂方法名称

-->

/**

* Spring 容器利用实例工厂方法创建对象

*/

@Test

public void createObjectInstanceFactory(){

ApplicationContext context =

new ClassPathXmlApplicationContext("applicationContext.xml")

HelloIoc staticFactory =

(HelloIoc) context.getBean("instance")

staticFactory.sayHello()

}

Spring 容器创建对象的时机

默认情况下,启动 spring 容器便创建对象

在spring的配置文件bean中有一个属性 lazy-init="default/true/false"

①、如果lazy-init为"default/false"在启动spring容器时创建对象(默认情况)

②、如果lazy-init为"true",在context.getBean时才要创建对象

在第一种情况下可以在启动spring容器的时候,检查spring容器配置文件的正确性,如果再结合tomcat,如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了内存中,如果有数据,则对内存来是一个消耗。

反过来,在第二种情况下,可以减少内存的消耗,但是不容易发现错误

spring的bean中的scope:"singleton/prototype/request/session/global session"

一、默认scope的值是singleton,即产生的对象是单例的

applicationContext.xml 文件中配置:

//spring 容器默认产生对象是单例的 scope="singleton"

@Test

public void test_scope_single_CreateObject(){

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml")

HelloIoc hello1 = (HelloIoc) context.getBean("helloIoc")

HelloIoc hello2 = (HelloIoc) context.getBean("helloIoc")

System.out.println(hello1.equals(hello2))//true

}

scope=“prototype”

多例模式,并且spring容器启动的时候并不会创建对象,而是在得到 bean 的时候才会创建对象

applicationContext.xml 文件中配置:

 总结:在单例模式下,启动 spring 容器,便会创建对象;在多例模式下,启动容器并不会创建对象,获得 bean 的时候才会创建对象

scope=“request” 每次HTTP请求都会创建一个新的bean

scope=“session”同一个HTTP Session共享一个Bean

scope=“global session” 同一个全局Session共享一个Bean,一般用于portlet应用环境

scope=“application”同一个Application 共享一个Bean

Spring 容器生命周期

/**

* Spring 容器的生命周期

* @author hadoop

*

*/

public class SpringLifeCycle {

public SpringLifeCycle(){

System.out.println("SpringLifeCycle")

}

//定义初始化方法

public void init(){

System.out.println("init...")

}

//定义销毁方法

public void destroy(){

System.out.println("destroy...")

}

public void sayHello(){

System.out.println("say Hello...")

}

}

applicationContext.xml

public void testSpringLifeCycle(){

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml")

SpringLifeCycle hello = (SpringLifeCycle) context.getBean("springLifeCycle")

hello.sayHello()

//销毁spring容器

ClassPathXmlApplicationContext classContext = (ClassPathXmlApplicationContext) context

classContext.close()

}

1、spring容器创建对象

2、执行init方法

3、调用自己的方法

4、当spring容器关闭的时候执行destroy方法

注意:当scope为"prototype"时,调用 close() 方法时是不会调用 destroy 方法的


欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/tougao/6045996.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-03-12
下一篇 2023-03-12

发表评论

登录后才能评论

评论列表(0条)

保存