三. Spring Boot 当中的“容器功能” 和 “配置绑定” 的详细剖析(附+源代码流程)

news2024/11/13 11:17:32

三. Spring Boot 当中的“容器功能” 和 “配置绑定” 的详细剖析(附+源代码流程)

文章目录

  • 三. Spring Boot 当中的“容器功能” 和 “配置绑定” 的详细剖析(附+源代码流程)
  • 1. Spring Boot 是继续支持了 Spring 当中的注解的
    • 1.2 Spring 当中的 @Component,@Controller,@Service,@Repository
    • 1.3 Spring Boot 中的 @Configuration
      • 1.3.1 @Bean 注解补充说明
      • 1.3.2 @Configuration 补充说明和注意事项,以及细节内容
    • 1.4 Spring Boot 中的@Import
    • 1.5 Spring Boot 中的 @Conditional
    • 1.6 Spring Boot 中的 @ImportResource
  • 2. Spring Boot 中的 配置绑定
    • 2.1 使用 Java 读取到 Spring Boot 核心配置文件 application.propert
    • 2.2 配置绑定的“注意事项和细节”
  • 3. 总结:
  • 4. 最后:


1. Spring Boot 是继续支持了 Spring 当中的注解的

1.2 Spring 当中的 @Component,@Controller,@Service,@Repository

Spring 注入组件的注解:

  • @Component
  • @Controller
  • @Service
  • @Repository

这些在 Spring 中传统的注解仍然有效,通过这些注解可以给容器注入组件。

演示测试:

这里我们仅仅测试一下 ,@Repository 注解,另外三个就不测试了,都是可以的。

  1. 首先,我们在 springboot 目录下,创建好一个bean 包,用于统一存放 Bean对象的类。

在这里插入图片描述

  1. 同时在该 bean 创建一个 A 类,同时给予上 @Repository 注解。

在这里插入图片描述

package com.rainbowsea.springboot.bean;


import org.springframework.stereotype.Repository;

@Repository
public class A {
}


  1. 在主程序中编写,测试获取该 A bean 类,看看是否被加入到了 ioc 容器管理起来了。

在这里插入图片描述

package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示Spring中传统的注解依然可以使用 @Controller,@Service, @Repository,@Component  start
        A aBean = ioc.getBean(A.class);
        System.out.println("aBean --" + aBean);

        // 演示Spring中传统的注解依然可以使用 @Controller,@Service, @Repository,@Component  end
    }
}

  1. 运行测试:

在这里插入图片描述

1.3 Spring Boot 中的 @Configuration

在Spring Boot当中可以通过 @Configuration注解来创建定义配置类,从而注入 Bean /组件

我们先来回顾传统方式如何通过配置文件(xml)注入组件/ 注入 Bean 对象,进行一个对比。

  1. 创建一个 名为 Monster的类 / Bean 对象

在这里插入图片描述

package com.rainbowsea.springboot.bean;


import org.springframework.stereotype.Repository;


public class Monster {

    private Integer id;
    private String name;
    private Integer age;
    private String skill;

    public Monster() {
    }

    public Monster(Integer id, String name, Integer age, String skill) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.skill = skill;
    }

    @Override
    public String toString() {
        return "Monster{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", skill='" + skill + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
}

  1. 在 resources 类路径下,创建一个名为 beans.xml 文件,为上述的 Monster 类/bean对象,进行一个 set 注入,纳入到 ioc 容器当中进行管理。
    在这里插入图片描述
<?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">

<!--    通过 xml 配置 Monster bean 注入到 ioc 容器当中去-->
    <bean id="monster03" class="com.rainbowsea.springboot.bean.Monster">
<!--       set 注入的方式-->
        <property name="name" value="牛魔王"></property>
        <property name="age" value="5000"></property>
        <property name="skill" value="封魔拳"></property>
        <property name="id" value="1000"></property>
    </bean>

</beans>
  1. 在主程序当中,获取该 bean 对象,看看是否 set 注入成功了。

在这里插入图片描述

package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import com.rainbowsea.springboot.bean.Monster;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示在Spring Boot 项目中,依然可以使用Spring的配置bean/注入bean/获取bean方式 start
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
        //ac.getBean("xml中配置的id",class)
        Monster monster03 = ac.getBean("monster03", Monster.class);
        System.out.println("monster03--" + monster03);
        // 演示在Spring Boot 项目,依然可以使用Spring的配置bean/注入bean/获取bean方式  end

        
    }
}

  1. 运行测试:

在这里插入图片描述

使用 SpringBoot 的@Configuration 添加/注入组件

  1. 创建一个 config 包,在该包下创建一个名为 Beanconfig 的类

在这里插入图片描述

  1. 在该类上标注上: @Configuration 注解:

@Configuration 标识这是一个配置类: 等价 配置文件。

程序员可以通过 @Bean 注解注入 bean对象到 ioc 容器当中

当一个类被 @Configuration 标识,则该类-Bean ,也会注入到容器当中,以配置类的形式存在于其中

在这里插入图片描述

  1. 在 BeanConfig 当中定义一个方法,同时在该方法上 加上 @Bean 注解。

@Bean : 给容器添加组件,就是 Monster bean。

monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id

这里:我们

monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id

new Monster(2000,“牛魔王”,5000,“芭蕉扇”) 注入到容器中具体的 Bean 信息

在这里插入图片描述

package com.rainbowsea.springboot.config;


import com.rainbowsea.springboot.bean.Monster;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/*
1. @Configuration  标识这是一个配置类: 等价  配置文件
2. 程序员可以通过 @Bean 注解注入bean对象到容器中
3. 当一个类被 @Configuration 标识,则该类-Bean ,也会注入到容器当中,以配置类的形式存在于其中
*/

@Configuration
public class BeanConfig {


    /*
    * 解读:
    * 1. @Bean : 给容器添加组件,就是 Monster bean
    * 2. monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id
    * 3. Monster: 注入类型,注入的bean的类型是Monster
    * 4. new Monster(2000,"牛魔王",5000,"芭蕉扇") 注入到容器中具体的Bean 信息
    * 5.     @Bean(name = {"monster_nmw"}) 在配置,注入Bean指定名字/id ,name是数组类型,可以定义多个
    * 6. 默认是单例注入的:(也就是说 getBean 获取到的都是同一个对象,共用)
    * 7. 通过    @Scope(value = "prototype") 可以每次返回一个新的对象,多例
    * */

    @Bean
    public Monster monster01(){
        return new Monster(2000,"牛魔王",5000,"芭蕉扇");
    }




}

  1. 运行测试:
    在这里插入图片描述
package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import com.rainbowsea.springboot.bean.Monster;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示 Spring Boot 项目中:     @Bean的方式 start
        Monster monster01 = ioc.getBean("monster01", Monster.class);
        System.out.println("monster01 --- " + monster01);

        // 演示 Spring Boot 项目中:     @Bean的方式 end


    }
}

在这里插入图片描述

1.3.1 @Bean 注解补充说明

在这里插入图片描述

  1. @Bean : 给容器添加组件,就是 Monster bean
  2. monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id
  3. Monster: 注入类型,注入的bean的类型是 Monster
  4. new Monster(2000,“牛魔王”,5000,“芭蕉扇”) 注入到容器中具体的Bean 信息
  5. @Bean(name = {“monster_nmw”}) 在配置,注入Bean指定名字/id ,name是数组类型,可以定义多个。如果 @Bean 没有指定 name/value的话,那么方法名 就是默认的 name/value属性的值 作为 id/名称 进行获取使用。

在这里插入图片描述

package com.rainbowsea.springboot.config;


import com.rainbowsea.springboot.bean.Monster;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/*
1. @Configuration  标识这是一个配置类: 等价  配置文件
2. 程序员可以通过 @Bean 注解注入bean对象到容器中
3. 当一个类被 @Configuration 标识,则该类-Bean ,也会注入到容器当中,以配置类的形式存在于其中
*/

@Configuration
public class BeanConfig {


    /*
    * 解读:
    * 1. @Bean : 给容器添加组件,就是 Monster bean
    * 2. monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id
    * 3. Monster: 注入类型,注入的bean的类型是Monster
    * 4. new Monster(2000,"牛魔王",5000,"芭蕉扇") 注入到容器中具体的Bean 信息
    * 5.     @Bean(name = {"monster_nmw"}) 在配置,注入Bean指定名字/id ,name是数组类型,可以定义多个
    * 6. 默认是单例注入的:(也就是说 getBean 获取到的都是同一个对象,共用)
    * 7. 通过    @Scope(value = "prototype") 可以每次返回一个新的对象,多例
    * */

    @Bean(name = {"monster_nmw"})
    public Monster monster01(){
        return new Monster(2000,"牛魔王",5000,"芭蕉扇");
    }




}

在这里插入图片描述

package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import com.rainbowsea.springboot.bean.Monster;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示 Spring Boot 项目中:     @Bean(name = {"monster_nmw"}) 自定义别名的方式 start
        Monster monster_nmw = ioc.getBean("monster_nmw", Monster.class);
        System.out.println("monster_nmw --- " + monster_nmw);
        // 演示 Spring Boot 项目中:     @Bean(name = {"monster_nmw"}) 自定义别名的方式 end



    }
}

在这里插入图片描述


在这里插入图片描述

  1. 默认是单例注入的:(也就是说 getBean 获取到的都是同一个对象,共用)


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示 @Configuration start
        Monster monster01 = ioc.getBean("monster01", Monster.class);
        Monster monster02 = ioc.getBean("monster01", Monster.class);
        System.out.println("monster01 ---" + monster01 + " " + monster01.hashCode());
        System.out.println("monster02 ---" + monster02 + " " + monster02.hashCode());

        // 特别说明:默认Spring Boot 是单例获取的 Bean对象的,叶就是获取到的Bean是同一个对象
        // 在对应的 Config配置类中定义:  @Scope(value = "prototype") 就是多例的了。
        // 演示 @Configuration end




    }
}

在这里插入图片描述

在这里插入图片描述

  1. 通过 @Scope(value = “prototype”) 可以每次返回一个新的对象,多例
    在这里插入图片描述

在这里插入图片描述

  1. 可以通过 @Bean配置多个 bean 对象。都是纳入到 ioc 容器当中进行管理起来的。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.3.2 @Configuration 补充说明和注意事项,以及细节内容

  1. @Configuration 标识这是一个配置类: 等价 配置文件
  2. 程序员可以通过 @Bean 注解注入bean对象到容器中
  3. 当一个类被 @Configuration 标识,则该类-Bean ,也会注入到容器当中,以配置类的形式存在于其中
  4. @Configuration 修饰标识的配置类-bean,也会被注入到ioc容器当中。这也是正常,可以理解的,因为你需要读取配置类上的信息,你不加入到 ioc 容器当中,Spring Boot 又怎么读取呢?

在这里插入图片描述

在这里插入图片描述

  1. 可以通过@Configuration ,定义多个配置类, 就和 Spring 可以有多个 ioc 配置文件是一个道理。同样的该多个配置类,也都会纳入到 ioc 容器当中进行管理起来。

在这里插入图片描述

  1. @Configuration 注意事项和细节: 自定义配置类的
  1. @Configuration 中有一个属性 proxyBeanMethods : 代理bean的方法。

在这里插入图片描述

  1. Full(proxyBeanMethods = true) 单例:保证每个@Bean方法被调用多少次返回的组件都是单实例的,是代理方式,是共用的 // 默认就是
  2. Lite(proxyBeanMethods = false) 多例: 每个@Bean方法被调用多少次,返回的组件都是新创建的,是非代理方式 ,非共用的,特别说明:proxyBeanMethods 是在调用 @Bean方法才生效,因此,需要先获取到对应 BeanConfig(配置类的组件),再从配置类组件的方法中,调用方法,获取到的Bean,而不是直接通过 SpringBoot 主程序的 ioc,getBean()直接得到容器来获取 bean,
  3. 注意观察直接通过ioc.getBean()获取 Bean, proxyBeanMethods 值并没有生效。
  4. 需要注意的是:@Configuration 是定义在类上的,所以配置 proxyBeanMethods应用 到该@Configuration注解标注的类当中的所有的方法上的
  5. 如何选择:组件依赖必须使用Full模式(默认就是 full模式),如果不需要组件依赖使用 Lite模式
  6. 当然,如果你仅仅只想要其中的一个对象,进行多例的话,就采用,@Scope("prototype") 在该返回对象的方法上,添加上该注解即可
  7. Lite 模式也称之为:“轻量级模式”,因为不检测依赖关系,运行速度快。

Full(proxyBeanMethods = true) 单例:保证每个@Bean方法被调用多少次返回的组件都是单实例的,是代理方式,是共用的 。记得把上面测试的,@Scope(value = “prototype”) 多例给去了

在这里插入图片描述

package com.rainbowsea.springboot.config;


import com.rainbowsea.springboot.bean.Monster;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;


/*
1. @Configuration  标识这是一个配置类: 等价  配置文件
2. 程序员可以通过 @Bean 注解注入bean对象到容器中
3. 当一个类被 @Configuration 标识,则该类-Bean ,也会注入到容器当中,以配置类的形式存在于其中
*/

@Configuration(proxyBeanMethods = true)  // 默认就是 true
public class BeanConfig {


    /*
    * 解读:
    * 1. @Bean : 给容器添加组件,就是 Monster bean
    * 2. monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id
    * 3. Monster: 注入类型,注入的bean的类型是Monster
    * 4. new Monster(2000,"牛魔王",5000,"芭蕉扇") 注入到容器中具体的Bean 信息
    * 5.     @Bean(name = {"monster_nmw"}) 在配置,注入Bean指定名字/id ,name是数组类型,可以定义多个
    * 6. 默认是单例注入的:(也就是说 getBean 获取到的都是同一个对象,共用)
    * 7. 通过    @Scope(value = "prototype") 可以每次返回一个新的对象,多例
    * */

    @Bean(name = {"monster01"})
    public Monster monster01(){
        return new Monster(2000,"牛魔王",5000,"芭蕉扇");
    }




}

在这里插入图片描述

package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import com.rainbowsea.springboot.bean.Monster;
import com.rainbowsea.springboot.config.BeanConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示@Configuration(ProxyBeanMethods = xxx) 单例/ 多例的设置  start

        // 先得到 BeanConfig 组件,再从 BeanConfig 组件中调用方法获得其它的Bean
        BeanConfig beanConfig = ioc.getBean(BeanConfig.class);

        Monster monster_01 = beanConfig.monster01();
        Monster monster_02 = beanConfig.monster01();

        System.out.println("monster_01 " + monster_01 + " " + monster_01.hashCode());
        System.out.println("monster_02 " + monster_02 + " " + monster_02.hashCode());
        // 演示@Configuration(ProxyBeanMethods = xxx) 单例/ 多例的设置  end
    }
}


Lite(proxyBeanMethods = false) 多例: 每个@Bean方法被调用多少次,返回的组件都是新创建的,是非代理方式 ,非共用的,特别说明:proxyBeanMethods 是在调用 @Bean方法才生效,因此,需要先获取到对应 BeanConfig(配置类的组件),再从配置类组件的方法中,调用方法,获取到的Bean,而不是直接通过 SpringBoot 主程序的 ioc,getBean()直接得到容器来获取 bean,

注意观察直接通过ioc.getBean()获取 Bean, proxyBeanMethods 值并没有生效。

在这里插入图片描述

在这里插入图片描述

注意观察直接通过ioc.getBean()获取 Bean, proxyBeanMethods 值并没有生效。

在这里插入图片描述

package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import com.rainbowsea.springboot.bean.Monster;
import com.rainbowsea.springboot.config.BeanConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示@Configuration(ProxyBeanMethods = xxx) 单例/ 多例的设置  start

        // 特别说明: proxyBeanMethods 是在调用@Bean方法才生效,因此,需要先获取BeanConfig 组件,再调用其中BeanConfig配置类组件中的方法获取
        // 1. 而不是直接通过 SpringBoot 主程序得到的容器来获取Bean(ioc.getBean()),注意观察直接通过ioc.getBean()获取是@Configuration
        // (ProxyBeanMethods = xxx) 属性配置是失效的(还是默认的单例)
        Monster monster01 = ioc.getBean("monster01", Monster.class);
        Monster monster02 = ioc.getBean("monster01", Monster.class);

        System.out.println("monster01 " + monster01 + " " + monster01.hashCode());
        System.out.println("monster02 " + monster02 + " " + monster02.hashCode());

    }
}

1.4 Spring Boot 中的@Import

@Import 也是可以注入组件/就是实现 Bean 对象纳入到 ioc 容器当中进行管理。

注意 @Import方式注入的组件/ 纳入 ioc 容器,获取默认组件/Bean对象时,用的名字就是该对应类的全类名。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

注意需要在 @Configuration 定义的配置类上的基础上,配置 @Import 才行

package com.rainbowsea.springboot.config;


import com.rainbowsea.springboot.bean.Cat;
import com.rainbowsea.springboot.bean.Dog;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Import(value = {Cat.class, Dog.class})  // 这样就拿到 ioc 容器到中去了。就可以被获取到了
@Configuration // 标识这是一个配置类
public class BeanConfig03 {
}

在这里插入图片描述

package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import com.rainbowsea.springboot.bean.Cat;
import com.rainbowsea.springboot.bean.Dog;
import com.rainbowsea.springboot.bean.Monster;
import com.rainbowsea.springboot.config.BeanConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);


        //  测试 @Import 使用 start
        Dog dogBean = ioc.getBean(Dog.class);
        Cat catBean = ioc.getBean(Cat.class);
        System.out.println("doBean -- " + dogBean);
        System.out.println("catBean--" + catBean);
        //  测试 @Import 使用 end

    }
}

运行测试:

在这里插入图片描述

1.5 Spring Boot 中的 @Conditional

@Conditional 是一个 条件装配:满足 Conditional 指定的条件,则进行组件注入(注入到 ioc 容器中,被 ioc 容器进行管理起来)。

@Conditional 是一个根注解,下面有很多扩展注解

在这里插入图片描述

在这里插入图片描述

演示在 SpringBoot, 如何通过 @ConditionalOnBean 来注入组件

**只有在容器中有 name = monster_nmw 组件时,才注入 dog01,使用 @ConditionalOnBean 注解中的 name 属性进行处理 **
在这里插入图片描述

在这里插入图片描述

package com.rainbowsea.springboot.config;


import com.rainbowsea.springboot.bean.Cat;
import com.rainbowsea.springboot.bean.Dog;
import com.rainbowsea.springboot.bean.Monster;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;


/*
1. @Configuration  标识这是一个配置类: 等价  配置文件
2. 程序员可以通过 @Bean 注解注入bean对象到容器中
3. 当一个类被 @Configuration 标识,则该类-Bean ,也会注入到容器当中,以配置类的形式存在于其中
*/

@Configuration(proxyBeanMethods = false)  // 默认就是 true
public class BeanConfig {


    /*
    * 解读:
    * 1. @Bean : 给容器添加组件,就是 Monster bean
    * 2. monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id
    * 3. Monster: 注入类型,注入的bean的类型是Monster
    * 4. new Monster(2000,"牛魔王",5000,"芭蕉扇") 注入到容器中具体的Bean 信息
    * 5.     @Bean(name = {"monster_nmw"}) 在配置,注入Bean指定名字/id ,name是数组类型,可以定义多个
    * 6. 默认是单例注入的:(也就是说 getBean 获取到的都是同一个对象,共用)
    * 7. 通过    @Scope(value = "prototype") 可以每次返回一个新的对象,多例
    * */

    @Bean(name = {"monster_nmw"})
    //@Scope(value = "prototype")
    public Monster monster01(){
        return new Monster(2000,"牛魔王",5000,"芭蕉扇");
    }


    /**
     * 1.@ConditionalOnBean(name="monster_nmw") 表示
     * 2.当容器中有一个Bean,名字是monster_nmw(类型不做约束,仅仅是 id /名字做约束),就注入dog01这个Dog bean
     * 3.如果ioc容器中,并没有一个叫 "monster_nmw" 的对象,该 Dog就不会注入 dog01的这个 Dog bean 对象到 ioc 容器当中
     * 4. 还有很多其它的条件约束注解,小伙伴可以自己测试
     * 5.注意:使用 @ConditionalOnBean 的同时,要将 @import 注解去了,因为 @import可以实现 ioc注入
     * 6. 注意:满足条件的,要放到判断的前面,简单的说就是,作为条件的bean要放到判断的bean的前面,不然是无法判断的
     * 7.     @ConditionalOnMissingBean(name = {"monster_nmw"})  没有名字/id 为 monster_nmw 才注入 dog01这个 Bean
     * 8. @ConditionalOnBean(name = {"monster_nmw"}) 也可以放在配置类,类的上面
     * 表示对该配置类的所有要注入的组件,都进行条件约束。
     * @return
     */
    @Bean  // 没有指明 name/value 则,默认方法名就是,获取对应 bean的名称/id
    @ConditionalOnBean(name = {"monster_nmw"})  // name 属性是个数组,可以写多个条件
    public Dog dog01() {
        return new Dog();
    }

}

运行测试:

在这里插入图片描述

@ConditionalOnBean(name="monster_nmw") 表示
当容器中有一个Bean,名字是monster_nmw(类型不做约束,仅仅是 id /名字做约束),就注入dog01这个Dog bean

在这里插入图片描述

运行测试:

在这里插入图片描述

还有一个名为 @ConditionalOnMissingBean的注解,与 .@ConditionalOnBean 相反。 ,表示@ConditionalOnMissingBean “表示非,就是没有该 name 上的属性的值的时候,该 Bean 就会被 ioc 容器管理起来”。

在这里插入图片描述

运行测试:

在这里插入图片描述


@Conditional小总结:

  1. @ConditionalOnBean(name=“monster_nmw”) 表示
  2. 当容器中有一个Bean,名字是monster_nmw(类型不做约束,仅仅是 id /名字做约束),就注入dog01这个Dog bean;如果ioc容器中,并没有一个叫 “monster_nmw” 的对象,该 Dog就不会注入 dog01的这个 Dog bean 对象到 ioc 容器当中
  3. 注意:使用 @ConditionalOnBean 的同时,要将 @import 注解去了,因为 @import可以实现 ioc注入
  4. 注意:满足条件的,要放到判断的前面,简单的说就是,作为条件的bean要放到判断的bean的前面,不然是无法判断的
  5. @ConditionalOnMissingBean(name = {“monster_nmw”}) 没有名字/id 为 monster_nmw 才注入 dog01这个 Bean;
  6. @ConditionalOnBean(name = {“monster_nmw”}) 也可以放在配置,类的上面示对该配置类的所有要注入的组件,都进行条件约束。
  7. 还有很多其它的条件约束注解,小伙伴可以自己测试。

在这里插入图片描述

1.6 Spring Boot 中的 @ImportResource

@ImportResource 作用:原生配置文件引入,也就是可以直接导入 **Spring ** 传统的 beans.xml ,可以认为是 Spring Boot 对 Spring 容器文件的兼容。

演示:beans.xml 导入到 BeanConfig.java 配置类,获取到 beanx.xml 注入/配置的组件。

这里我们创建新的 BeanConfig3.java(建议创建新的配置类) 来测试, 使用@ImportResource 导入 beans.xml

在这里插入图片描述

在这里插入图片描述

package com.rainbowsea.springboot.config;


import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;

@Configuration  // 标注配置类
// 导入 beans.xml 就可以获取到 beans.xml 中配置 bean
// 就是导入在 beans.xml 文件中配置的的 bean对象里面是 monster03 对象bena
// 注意:不要忘记了 Spring ,通过 xml 文件也是可以导入到 ioc 容器当中的
// locations 是数组类型,可以配置多个
// 流程是:在配置类当中——> 添加上@ImportResource(指明bean 的xml 路径,一般是类路径下,通过xml实现的bean 加入到ioc)
@ImportResource(locations = {"classpath:beans.xml","classpath:beans02.xml"})
public class BeanConfig3 {
}

在这里插入图片描述

package com.rainbowsea.springboot;


import com.rainbowsea.springboot.bean.A;
import com.rainbowsea.springboot.bean.Cat;
import com.rainbowsea.springboot.bean.Dog;
import com.rainbowsea.springboot.bean.Monster;
import com.rainbowsea.springboot.config.BeanConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


// @SpringBootApplication  表示是一个 springboot 应用
// 直接在    SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
 @SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
    public static void main(String[] args) {
        // 启动 SpringBoot 应用程序
        ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);

        // 演示 @ImportResource 使用 start
        Monster monster03 = ioc.getBean("monster03", Monster.class);
        System.out.println("monster03-" + monster03);
        System.out.println("monster03 bean 是否存在到 ioc 容器中" + ioc.containsBean("monster03"));

        // 演示 @ImportResource 使用 end

    }
}

@ImportResource 简单的说就是:可以通过@ImportResource 注解,到配置类上,在配置类上指定 配置好的 Bean 对象的 xml 文件,就可以将该 Bean 对象放入到 ioc 容器当中,同时又可以被获取到。

2. Spring Boot 中的 配置绑定

2.1 使用 Java 读取到 Spring Boot 核心配置文件 application.propert

简单的说:就是一句话:使用Java读取到 Spring Boot 核心配置文件application.properties 的内容,并且把它封装到对应的 JavaBean 当中去。

演示:application.properties 指定 k-vJavaBean 绑定。

  1. 在 bean目录下,创建一个 Furn 类。

在这里插入图片描述

package com.rainbowsea.springboot.bean;

public class Furn {
    private Integer id;
    private String name;
    private Double price;


    public Furn() {
    }

    public Furn(Integer id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }


    @Override
    public String toString() {
        return "Furn{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

  1. application.properties 文件当中配置 注入到 Furn 类属性当中值。
# 设置Furn的属性k-v
# 前面的furn01 是用于指定/区别不同绑定对象,这样可以再绑定Furn bean 属性值时
# 通过 furn01 前缀进行区分
# 不要有空格
# furn01.id 中的id,就是你要绑定的Furn bean 的属性名,不可以随便写,如果写错了,对应不上,那么对应的bean对象中的属性就为 null了
furn01.id=100
furn01.name=TV
furn01.price=100.99

在这里插入图片描述

  1. 在 Furn 类上添加:@ConfigurationProperties 注解:
  2. 在这里插入图片描述

格式

@ConfigurationProperties(prefix = "在application.properties文件当中配置的前缀"

在这里插入图片描述

package com.rainbowsea.springboot.bean;


import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component // 注入到 ioc 容器当中
@ConfigurationProperties(prefix = "furn01")  // prefix = "前缀"
public class Furn {
    private Integer id;
    private String name;
    private Double price;


    public Furn() {
    }

    public Furn(Integer id, String name, Double price) {
        this.id = id;
        this.name = name;
        this.price = price;
    }


    @Override
    public String toString() {
        return "Furn{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", price=" + price +
                '}';
    }


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }
}

  1. 装配上 Furn 类。我们将其显示到浏览器上(以 JSON的方式显示)

在这里插入图片描述

package com.rainbowsea;


import com.rainbowsea.springboot.bean.Furn;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

@Controller // 注入到 ioc 容器当中
public class HiController {


    //将 Furn  装配到 HiController 类当中
    // 装配完了,则furn 类的属性值,就是你在 application.properties当中配置的值
    @Resource
    private Furn furn;




    @RequestMapping("/furn")  // 映射路径
    @ResponseBody  // 表示返回的是一个json/字符串,不是一个页面
    public Furn furn(){
        return furn;
    }

}

  1. 启动运行测试:

在这里插入图片描述

其实配置绑定还有第2种方式,只是这种方式不常用,这里我们也学习一下,效果是一样的。

注意:使用该方式,需要注销掉 Furn 也就是(对应Bean类)上的 @Compoent 注解,否则会报错。

然后我们需要在一个 **配置类**上加上一个 @EnableConfigurationProperties(对应的Bean.class)注解
在这里插入图片描述

在这里插入图片描述

package com.rainbowsea.springboot.config;


import com.rainbowsea.springboot.bean.Furn;
import com.rainbowsea.springboot.bean.Monster;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration  // 标注是配置类
@EnableConfigurationProperties({Furn.class})
public class BeanConfig02 {

}

运行测试:

在这里插入图片描述

2.2 配置绑定的“注意事项和细节”

  1. 如果 application.properties 有中文, 需要转成 unicode 编码写入, 否则出现乱码

在这里插入图片描述

解决方法:

我们只需要去网上随便找一个,可以将 中文转换为 unicode编码 的网站,将转换为的 unicode 复制替换一下就OK了。

在这里插入图片描述

运行测试:

在这里插入图片描述

  1. furn01.id 中的id,就是你要绑定的Furn bean 的属性名,不可以随便写,如果写错了,对应不上,那么对应的bean对象中的属性就为 null了

在这里插入图片描述

测试:

在这里插入图片描述

  1. 使用 @ConfigurationProperties(prefix = “furn01”) 会提示如下信息 但是不会影响使用
    在这里插入图片描述

解决方法:

解决 @ConfigurationProperties(prefix = “furn01”) 提示信息, 在 pom.xml 增加依赖, 即可

依赖如下:

在这里插入图片描述

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional>
        </dependency>

在这里插入图片描述

3. 总结:

  1. Spring Boot 是继续支持了 Spring 当中的注解的:例如:@Component,@Controller,@Service,@Repository。
  2. @Configuraion注解:在Spring Boot当中可以通过 @Configuration注解来创建定义配置类,从而注入 Bean / 组件
  1. @Configuration 标识这是一个配置类: 等价 配置文件
  2. 程序员可以通过 @Bean 注解注入bean对象到容器中
  3. 当一个类被 @Configuration 标识,则该类-Bean ,也会注入到容器当中,以配置类的形式存在于其中
  4. @Configuration 修饰标识的配置类-bean,也会被注入到ioc容器当中。这也是正常,可以理解的,因为你需要读取配置类上的信息,你不加入到 ioc 容器当中,Spring Boot 又怎么读取呢?
  5. 可以通过@Configuration ,定义多个配置类, 就和 Spring 可以有多个 ioc 配置文件是一个道理。同样的该多个配置类,也都会纳入到 ioc 容器当中进行管理起来。
  6. @Configuration 注意事项和细节: 自定义配置类的

@Configuration 中有一个属性 proxyBeanMethods : 代理bean的方法。

  1. Full(proxyBeanMethods = true) 单例:保证每个@Bean方法被调用多少次返回的组件都是单实例的,是代理方式,是共用的 // 默认就是
  2. Lite(proxyBeanMethods = false) 多例: 每个@Bean方法被调用多少次,返回的组件都是新创建的,是非代理方式 ,非共用的,特别说明:proxyBeanMethods 是在调用 @Bean方法才生效,因此,需要先获取到对应 BeanConfig(配置类的组件),再从配置类组件的方法中,调用方法,获取到的Bean,而不是直接通过 SpringBoot 主程序的 ioc,getBean()直接得到容器来获取 bean,
  3. 注意观察直接通过ioc.getBean()获取 Bean, proxyBeanMethods 值并没有生效。
  4. 需要注意的是:@Configuration 是定义在类上的,所以配置 proxyBeanMethods应用 到该@Configuration注解标注的类当中的所有的方法上的
  5. 如何选择:组件依赖必须使用Full模式(默认就是 full模式),如果不需要组件依赖使用 Lite模式
  6. 当然,如果你仅仅只想要其中的一个对象,进行多例的话,就采用,@Scope("prototype") 在该返回对象的方法上,添加上该注解即可
  7. Lite 模式也称之为:“轻量级模式”,因为不检测依赖关系,运行速度快。
  1. @Bean : 给容器添加组件,就是 Monster bean。@Configuration 注解是配合 @Bean 使用的
  1. @Bean : 给容器添加组件,就是 Monster bean
  2. monster01() : 默认:你的方法名monster01,作为 Bean 的名字/id
  3. Monster: 注入类型,注入的bean的类型是 Monster
  4. new Monster(2000,“牛魔王”,5000,“芭蕉扇”) 注入到容器中具体的Bean 信息
  5. @Bean(name = {“monster_nmw”}) 在配置,注入Bean指定名字/id ,name是数组类型,可以定义多个。如果 @Bean 没有指定 name/value的话,那么方法名 就是默认的 name/value属性的值 作为 id/名称 进行获取使用。
  6. 默认是单例注入的:(也就是说 getBean 获取到的都是同一个对象,共用)
  7. 通过 @Scope(value = “prototype”) 可以每次返回一个新的对象,多例
  8. 可以通过 @Bean配置多个 bean 对象。都是纳入到 ioc 容器当中进行管理起来的。
  1. @Import注解: 也是可以注入组件/就是实现 Bean 对象纳入到 ioc 容器当中进行管理。注意 @Import方式注入的组件/ 纳入 ioc 容器,获取默认组件/Bean对象时,用的名字就是该对应类的全类名。
  2. @Conditional 是一个 条件装配:满足 Conditional 指定的条件,则进行组件注入(注入到 ioc 容器中,被 ioc 容器进行管理起来)。
  1. @ConditionalOnBean(name=“monster_nmw”) 表示
  2. 当容器中有一个Bean,名字是monster_nmw(类型不做约束,仅仅是 id /名字做约束),就注入dog01这个Dog bean;如果ioc容器中,并没有一个叫 “monster_nmw” 的对象,该 Dog就不会注入 dog01的这个 Dog bean 对象到 ioc 容器当中
  3. 注意:使用 @ConditionalOnBean 的同时,要将 @import 注解去了,因为 @import可以实现 ioc注入
  4. 注意:满足条件的,要放到判断的前面,简单的说就是,作为条件的bean要放到判断的bean的前面,不然是无法判断的
  5. @ConditionalOnMissingBean(name = {“monster_nmw”}) 没有名字/id 为 monster_nmw 才注入 dog01这个 Bean;
  6. @ConditionalOnBean(name = {“monster_nmw”}) 也可以放在配置,类的上面示对该配置类的所有要注入的组件,都进行条件约束。
  7. 还有很多其它的条件约束注解,小伙伴可以自己测试。

在这里插入图片描述

  1. @ImportResource注解: 作用:原生配置文件引入,也就是可以直接导入 **Spring ** 传统的 beans.xml ,可以认为是 Spring Boot 对 Spring 容器文件的兼容。

  2. Spring Boot 中的配置绑定:简单的说:就是一句话:使用Java读取到 Spring Boot 核心配置文件application.properties 的内容,并且把它封装到对应的 JavaBean 当中去。

注意Spring Boot中配置绑定,文章中所提到的 3 个注意事项,以及解决方式。

4. 最后:

“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”

在这里插入图片描述

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

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

相关文章

通过visual studio进行dump文件调试和分析

0、前言 很多时候程序crash之后需要分析原因。对于C/C程序&#xff0c;一般最常见的场景和方法就是根据dump文件进行分析。 1、分析的前提条件 进行dump文件分析&#xff0c;需要以下文件&#xff1a; 进程crash时产生的dump文件程序源码进程对应的程序exe文件编译exe文件时产…

QT Quick QML 添加海康威视SDK云台控制模块

文章目录 1. 配置海康威视 SDK 下载SDK文件移植工程文件添加 2. 函数调用流程接口参考代码 3. 代码后端核心代码前端核心代码 GitHub 源码: QmlLearningPro &#xff0c;选择子工程 HkwsDemo.pro &#xff08;暂未上传&#xff09; QML 其它文章请点击这里: QT QUICK …

Monibuca实战:如何用Go语言打造高效的直播后端

简介 Monibuca&#xff08;简称&#xff1a;m7s&#xff09; 是一个开源的实时流媒体服务器开发框架&#xff0c;使用 Go 语言编写。 它的设计目标是提供一个高性能、可扩展、易于定制的实时流媒体服务器解决方案。 Monibuca 的核心理念是模块化&#xff0c;允许开发者根据需…

文件禁止外发的方法有哪些?企业如何禁止文件外发:六个控制文件外发的小窍门!

想象一下&#xff0c;企业信息如同珍贵的宝藏&#xff0c;而文件外发就像不经意间打开的后门&#xff0c;让宝藏暴露在风雨之中&#xff01;今天&#xff0c;我们就来聊聊如何给这扇后门加上六道坚实的锁&#xff0c;确保企业信息的安全无虞。让我们一起探索六个控制文件外发的…

Mask R-CNN论文原理讲解

论文:arxiv.org/pdf/1703.06870 代码&#xff1a;maskrcnn-benchmark:Fast, modular reference implementation of Instance Segmentation and Object Detection algorithms in PyTorch. - GitCode Mask R-CNN简介 Mask R-CNN是何凯明大神的新作。Mask R-CNN是一种在有效检测…

武器弹药制造5G智能工厂物联数字孪生平台,推进制造业数字化转型

武器弹药制造领域作为国防工业的重要组成部分&#xff0c;其数字化转型更是关乎国家安全与军事实力提升的关键。随着5G、物联网、大数据、云计算及人工智能等先进技术的融合应用&#xff0c;武器弹药制造5G智能工厂物联数字孪生平台应运而生&#xff0c;正逐步成为推进制造业数…

分享5款支持论文写作网站先稿后付的网站!

在当今学术研究和学术写作领域&#xff0c;AI论文写作工具已经成为不可或缺的助手。这些工具不仅能够提高写作效率&#xff0c;还能帮助研究人员生成高质量的论文内容。特别是那些提供“先稿后付”服务模式的网站&#xff0c;更是为用户提供了极大的便利和保障。以下是五款值得…

记录|SPC公式小结

目录 前言一、基本缩写二、Xbar和R的控制线三、相关系数表更新时间 前言 参考文章&#xff1a; 参考视频&#xff1a; SPC公式小结 一、基本缩写 二、Xbar和R的控制线 三、相关系数表 更新时间 2024.08.29&#xff1a;创建

旗帜分田(华为od机考题)

一、题目 1.原题 从前有个村庄&#xff0c;村民们喜欢在各种田地上插上小旗子&#xff0c;旗子上标识了各种不同的数字。 某天集体村民决定将覆盖相同数字的最小矩阵形的土地的分配给为村里做出巨大贡献的村民&#xff0c; 请问&#xff0c;此次分配土地&#xff0c;做出贡献…

DevEco Studio5 新建项目

Deveco Studio安装结束之后&#xff0c;开始新建一个项目&#xff1a; 1.点击Create Project新建项目 2.选择空的项目–>点击next 3.配置项目信息–>点击Finish 4.进入项目 6.右上方目前处于No Devices(无设备)状态–>点击下拉三角–>点击Devide Manager管理设…

Life long learning

现象&#xff1a;一个model进行multi-task learning做的还可以&#xff0c;说明模型是可以同时学会多个任务的&#xff0c;但是如果训练过程是1个task 1个task的顺序进行&#xff0c;模型就会发生灾难性的遗忘现象&#xff0c;只会做刚学完的task。 目标&#xff1a;让模型不要…

94.WEB渗透测试-信息收集-Google语法(8)

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a; 易锦网校会员专享课 上一个内容&#xff1a;93.WEB渗透测试-信息收集-Google语法&#xff08;7&#xff09; • Filetype • Filetype…

二叉树前序,中序,后序非递归遍历(Java)

1. 思路&#xff1a; 首先创建一个栈和顺序表&#xff0c;按照根左右的前序遍历顺序去遍历这棵树&#xff0c;一直往左孩子方向遍历&#xff0c;每遍历到一个结点就入栈并且加入到顺序表里&#xff0c;如果没有左孩子了&#xff0c;就拿出栈顶元素&#xff0c;看它是否有右孩子…

2024年牛客网最全1000道Java中高级面试题包含答案详解,看完稳了

我相信大多 Java 开发的程序员或多或少经历过 BAT 一些大厂的面试&#xff0c;也清楚一线互联网大厂 Java 面试是有一定难度的&#xff0c;小编经历过多次面试&#xff0c;有满意的也有备受打击的。因此呢小编想把自己这么多次面试经历以及近期的面试真题来个汇总分析&#xff…

JavaScript进阶指南之Event Loop

JavaScript进阶指南之Event Loop 引言 简要介绍主题&#xff1a; 在JavaScript的世界中&#xff0c;Event Loop是一个核心机制&#xff0c;它决定了代码的执行顺序&#xff0c;尤其是在处理异步任务时。对于初学者来说&#xff0c;理解Event Loop的工作原理是迈向JavaScript进…

设计模式篇(DesignPattern - 结构型模式)(持续更新迭代)

目录 模式一&#xff1a;适配器模式 一、简介 二、案例一&#xff08;充电器问题&#xff09; 1. 类适配器 2. 对象适配器 3. 接口适配器 三、应用 1. HandlerAdapter&#xff08;SpringMVC 源码应用&#xff09; 四、总结 模式二&#xff1a;桥接模式 一、简介 1.…

20240829版图的层次

1 最常用 Esc&#xff1a;取消操作 i&#xff1a;插入元件版图 c&#xff1a;复制 m&#xff1a;移动 u&#xff1a;撤销上一步操作 q&#xff1a;查看属性 f&#xff1a;全局视图 e&#xff1a;显示设置&#xff08;图层、栅格、走线模式等&#xff09; r&#xff1a;矩形填充…

纷享AI PaaS 助力打造企业级Al专属应用

纷享AIPaaS助力打造企业级Al专属应用 纷享销客人工智能(AI)在多个关键领域下的应用&#xff0c;诸如营销内容生成、线索预测评分、客服工作台助手等&#xff0c;均是通过AIPaaS平台来定制实现。 纷享销客AIPaaS平台通过AgentBuilder和ModelBuilder为上层的场景应用提供底层能…

005-CircuitBreaker断路器-Resilience4J

文章目录 1 CircuitBreaker1.1 实现原理1.2 一句话 2 Resilience4J2.1 是什么2.2 能干嘛2.3 怎么用 3 熔断(CircuitBreaker)(服务熔断服务降级)3.1 断路器三大状态3.2断路器3大状态之前的转换3.3断路器所有配置参数参考3.4 熔断降级案例需求说明3.5 COUNT_BASED(计数的滑动窗口…

6个一键生成原创文案实用方法,亲测好用!

在当下的这个自媒体时代&#xff0c;文案创作的需求日益增长。无论是用于社交媒体、广告宣传还是各种内容创作&#xff0c;优质的原创文案都能起到关键作用。但有时候&#xff0c;我们在创作文案的过程中可能会陷入灵感枯竭的困境。但别担心&#xff0c;这里有6个一键生成原创文…