Mr. Cappuccino的第60杯咖啡——Spring之BeanFactory和ApplicationContext

news2024/11/24 4:09:09

Spring之BeanFactory和ApplicationContext

    • 类图
    • BeanFactory
      • 概述
      • 功能
        • 项目结构
        • 项目代码
        • 运行结果
        • 总结
    • ApplicationContext
      • 概述
      • 功能
        • MessageSource(国际化的支持)
          • 概述
          • 项目结构
          • 项目代码
          • 运行结果
        • ResourcePatternResolver(匹配资源路径)
          • 概述
          • 项目结构
          • 项目代码
          • 运行结果
        • EnvironmentCapable(环境变量配置)
          • 项目结构
          • 项目代码
          • 运行结果
        • ApplicationEventPublisher(事件发布)
          • 项目结构
          • 项目代码
          • 运行结果
    • ApplicationContext实现类
      • 基于XML方式
        • 项目结构
        • 项目代码
        • 运行结果
      • 基于磁盘目录XML方式
        • 项目结构
        • 项目代码
        • 运行结果
      • 基于注解方式
        • @Import
          • 项目结构
          • 项目代码
          • 运行结果
        • @Conditional
          • 项目结构
          • 项目代码
          • 运行结果

类图

在这里插入图片描述

BeanFactory

概述

  1. BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它是负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖;
  2. BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,其中XmlBeanFactory就是常用的一种,该实现将以XML方式描述组成应用的对象及对象间的依赖关系。XmlBeanFactory类将持有此XML配置元数据,并用它来构建一个完全可配置的系统或应用;
  3. 它为其他具体的IOC容器提供了最基本的规范,例如DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等具体的容器都是实现了BeanFactory,再在其基础之上附加了其他的功能;
  4. 原始的BeanFactory无法支持Spring的许多插件,如AOP功能、Web应用等。ApplicationContext接口,它由BeanFactory接口派生而来。现在一般使用ApplicationnContext,其不但包含了BeanFactory的作用,同时还进行更多的扩展;

功能

项目结构

在这里插入图片描述

项目代码

pom.xml

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>spring-bean-factory</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>

</project>

AutowireBean.java

package com.spring.bean;

/**
 * @author honey
 * @date 2023-08-10 14:51:07
 */
public class AutowireBean {

    public void autowire(){
        System.out.println("AutowireBean==autowire()");
    }
}

UserBean.java

package com.spring.bean;

import org.springframework.beans.factory.annotation.Autowired;

/**
 * @author honey
 * @date 2023-08-10 14:08:14
 */
public class UserBean {

    @Autowired
    private AutowireBean autowireBean;

    public void to() {
        System.out.println("UserBean==to()");
        autowireBean.autowire();
    }
}

SpringConfig.java

package com.spring.config;

import com.spring.bean.AutowireBean;
import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author honey
 * @date 2023-08-10 14:08:44
 */
@Configuration
public class SpringConfig {

    @Bean
    public UserBean userBean(){
        return new UserBean();
    }

    @Bean
    public AutowireBean autowireBean(){
        return new AutowireBean();
    }
}

SpringTest01.java

package com.spring.test;

import com.spring.bean.UserBean;
import com.spring.config.SpringConfig;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.AnnotationConfigUtils;

import java.util.Arrays;
import java.util.Collection;

/**
 * @author honey
 * @date 2023-08-10 14:09:39
 */
public class SpringTest01 {

    public static void main(String[] args) {
        // 初始化BeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // 获取SpringConfig对应的BeanDefinition
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SpringConfig.class).getBeanDefinition();
        // 将BeanDefinition注册到BeanFactory中
        beanFactory.registerBeanDefinition("springConfig", beanDefinition);
        // 注册注解相关配置的处理器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        // 通过BeanFactory后置处理器处理SpringConfig中配置的bean(ConfigurationClassPostProcessor)
        Collection<BeanFactoryPostProcessor> beanFactoryPostProcessors = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values();
        beanFactoryPostProcessors.forEach(
                (beanFactoryPostProcessor) -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory)
        );
        // 通过Bean对象后置处理器处理依赖注入@Autowired(AutowiredAnnotationBeanPostProcessor)和@Resource(CommonAnnotationBeanPostProcessor)
        Collection<BeanPostProcessor> beanPostProcessors = beanFactory.getBeansOfType(BeanPostProcessor.class).values();
        beanPostProcessors.forEach(
                beanFactory::addBeanPostProcessor
        );
        // 提前初始化单例对象(饿汉式)
        beanFactory.preInstantiateSingletons();
        // 默认情况下延迟加载(懒汉式)
        UserBean userBean = beanFactory.getBean("userBean", UserBean.class);
        userBean.to();
        System.out.println(userBean);

        System.out.println("-------------");

        // 输出所有注册到BeanFactory中的beanName
        Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach((beanName) -> System.out.println("beanName:" + beanName));

    }
}

运行结果

在这里插入图片描述

总结

DefaultListableBeanFactory作为BeanFactory的默认实现类,该类中维护了存储Bean对象的map集合,BeanFactory主要负责生产和管理Bean对象。


// 注册注解相关配置的处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

AnnotationConfigUtils.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


// 通过BeanFactory后置处理器处理SpringConfig中配置的bean(ConfigurationClassPostProcessor)
Collection<BeanFactoryPostProcessor> beanFactoryPostProcessors = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values();
beanFactoryPostProcessors.forEach(
        (beanFactoryPostProcessor) -> beanFactoryPostProcessor.postProcessBeanFactory(beanFactory)
);

ConfigurationClassPostProcessor:用于从BeanFactory中检测使用了@Configuration注解的类,并将这些类中使用了@Bean注解的方法生成BeanDefinition,注册到BeanFactory中。

ConfigurationClassPostProcessor.java

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

EventListenerMethodProcessor:主要用于处理@EventListener注解。


// 通过Bean对象后置处理器处理依赖注入@Autowired(AutowiredAnnotationBeanPostProcessor)和@Resource(CommonAnnotationBeanPostProcessor)
Collection<BeanPostProcessor> beanPostProcessors = beanFactory.getBeansOfType(BeanPostProcessor.class).values();
beanPostProcessors.forEach(
        beanFactory::addBeanPostProcessor
);

AutowiredAnnotationBeanPostProcessor: 主要用于处理@Autowired注解。

AutowiredAnnotationBeanPostProcessor.java

在这里插入图片描述

CommonAnnotationBeanPostProcessor:主要用于处理@Resource注解。

CommonAnnotationBeanPostProcessor.java

在这里插入图片描述


// 提前初始化单例对象(饿汉式)
beanFactory.preInstantiateSingletons();

BeanFactory默认采用延迟加载的形式来注入Bean。


BeanFactoryPostProcessor:BeanFactory的后置处理器,是实现spring容器功能扩展的重要接口;
BeanPostProcessor:Bean对象的后置处理器,负责对已创建好的bean对象进行加工处理;

BeanPostProcessor中的两个核心方法:
postProcessBeforeInitialization:在任何初始化方法执行之前执行该方法,如InitializingBean的afterPropertiesSet方法;
postProcessAfterInitialization:在任何初始化方法执行之后执行该方法,如InitializingBean的afterPropertiesSet方法;


ApplicationContext

概述

ApplicationContext的中文意思是“应用程序上下文”,它继承自BeanFactory接口,除了包含BeanFactory的所有功能之外,在国际化支持、资源访问(如URL和文件)、事件传播等方面进行了良好的支持,被推荐为Java EE应用之首选,可应用在Java APP与Java Web中。

  1. MessageSource(国际化的支持)
  2. ResourcePatternResolver(匹配资源路径)
  3. EnvironmentCapable(环境变量配置)
  4. ApplicationEventPublisher(事件发布)

在这里插入图片描述

功能

MessageSource(国际化的支持)

概述

MessageSource是Spring中的转换消息接口,提供了国际化信息的能力。MessageSource用于解析消息,并支持消息的参数化和国际化。Spring包含两个内置的MessageSource实现:ResourceBundleMessageSource和ReloadableResourceBundleMessageSource。

项目结构

在这里插入图片描述

项目代码

pom.xml

<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com</groupId>
    <artifactId>spring-application-context</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>

</project>

SpringConfig.java

package com.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;

/**
 * @author honey
 * @date 2023-08-11 01:30:48
 */
@Configuration
public class SpringConfig {

    @Bean
    public ResourceBundleMessageSource messageSource() {
        ResourceBundleMessageSource source = new ResourceBundleMessageSource();
        // 设置基础名
        source.setBasenames("messages/message");
        // 设置编码
        source.setDefaultEncoding("UTF-8");
        return source;
    }
}

在resources目录下创建文件夹messages,并在messages文件夹下新增两个配置文件,分别是message_en.properties和message_zh.properties。

message_en.properties

test=test

message_zh.properties

test=测试

SpringTest01.java

package com.spring.test;

import com.spring.config.SpringConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ResourceBundleMessageSource;

import java.util.Locale;

/**
 * @author honey
 * @date 2023-08-11 01:33:10
 */
public class SpringTest01 {

    public static void main(String[] args) {
    	// MessageSource(国际化的支持)
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        ResourceBundleMessageSource messageSource = applicationContext.getBean("messageSource", ResourceBundleMessageSource.class);
        System.out.println("中文:" + messageSource.getMessage("test", null, Locale.CHINESE));
        System.out.println("英文:" + messageSource.getMessage("test", null, Locale.ENGLISH));
    }
}
运行结果

在这里插入图片描述

ResourcePatternResolver(匹配资源路径)

概述

ResourcePatternResolver用于解析带有*等通配符路径的资源文件,是ResourceLoader接口的拓展接口。

classpath: 只会从target/classes目录下查找文件;
classpath*: 不仅会从target/classes目录下查找文件,还会从所依赖的Jar包中查找文件;

项目结构

在这里插入图片描述

项目代码

application.properties

name=honey

SpringTest02.java

package com.spring.test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.io.Resource;

import java.io.IOException;
import java.util.Arrays;

/**
 * @author honey
 * @date 2023-08-11 02:09:51
 */
public class SpringTest02 {

    public static void main(String[] args) throws IOException {
        // ResourcePatternResolver(匹配资源路径)
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        System.out.println("-------------------------------------------------------------");
        System.out.println("读取resources目录下的application.properties");
        Resource[] resources1 = applicationContext.getResources("classpath:application.properties");
        Arrays.stream(resources1).forEach(System.out::println);
        System.out.println("-------------------------------------------------------------");
        System.out.println("读取spring-beans-5.2.1.RELEASE.jar!/META-INF/spring.factories");
        Resource[] resources2 = applicationContext.getResources("classpath*:META-INF/spring.factories");
        Arrays.stream(resources2).forEach(System.out::println);
    }
}
运行结果

在这里插入图片描述

EnvironmentCapable(环境变量配置)

项目结构

在这里插入图片描述

项目代码

SpringTest03.java

package com.spring.test;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

/**
 * @author honey
 * @date 2023-08-11 02:31:12
 */
public class SpringTest03 {

    public static void main(String[] args) {
        // EnvironmentCapable(环境变量配置)
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        String javaHome = environment.getProperty("java_home");
        String env = environment.getProperty("env");
        System.out.println("java_home:" + javaHome);
        System.out.println("env:" + env);
    }
}
运行结果

在启动时需要加上环境变量参数


方式一

在这里插入图片描述


方式二

在这里插入图片描述
在这里插入图片描述


在这里插入图片描述

ApplicationEventPublisher(事件发布)

项目结构

在这里插入图片描述

项目代码

UserInfoEvent.java

package com.spring.event;

import org.springframework.context.ApplicationEvent;

/**
 * @author honey
 * @date 2023-08-11 02:42:37
 */
public class UserInfoEvent extends ApplicationEvent {

    /**
     * source事件源
     *
     * @param source source
     */
    public UserInfoEvent(Object source) {
        super(source);
    }
}

EmailListener.java

package com.spring.listener;

import com.spring.event.UserInfoEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * @author honey
 * @date 2023-08-11 02:44:35
 */
@Component
public class EmailListener {

    @EventListener
    public void emailListener(UserInfoEvent userInfoEvent) {
        System.out.println("当前监听器:emailListener,userInfoEvent:" + userInfoEvent);
    }
}

PhoneListener.java

package com.spring.listener;

import com.spring.event.UserInfoEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;

/**
 * @author honey
 * @date 2023-08-11 02:46:40
 */
@Component
public class PhoneListener {

    @EventListener
    public void phoneListener(UserInfoEvent userInfoEvent) {
        System.out.println("当前监听器:phoneListener,userInfoEvent:" + userInfoEvent);
    }
}

SpringConfig02.java

package com.spring.config;

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

/**
 * @author honey
 * @date 2023-08-11 02:48:54
 */
@Configuration
@ComponentScan(value = {"com.spring.listener"})
public class SpringConfig02 {
}

SpringTest04.java

package com.spring.test;

import com.spring.config.SpringConfig02;
import com.spring.event.UserInfoEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author honey
 * @date 2023-08-11 02:47:25
 */
public class SpringTest04 {

    public static void main(String[] args) {
        // ApplicationEventPublisher(事件发布)
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig02.class);
        applicationContext.publishEvent(new UserInfoEvent(applicationContext));
    }
}
运行结果

在这里插入图片描述

ApplicationContext实现类

基于XML方式

项目结构

在这里插入图片描述

项目代码

UserBean.java

package com.spring.bean;

/**
 * @author honey
 * @date 2023-08-11 03:11:09
 */
public class UserBean {
}

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

    <bean id="userBean" class="com.spring.bean.UserBean"/>

</beans>

SpringTest05.java

package com.spring.test;

import com.spring.bean.UserBean;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author honey
 * @date 2023-08-11 03:11:51
 */
public class SpringTest05 {

    public static void main(String[] args) {
        // 读取spring.xml
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        // 从IOC容器中读取对象
        UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
        System.out.println(userBean);
    }
}

运行结果

在这里插入图片描述

基于磁盘目录XML方式

项目结构

在这里插入图片描述

项目代码

在这里插入图片描述

SpringTest06.java

package com.spring.test;

import com.spring.bean.UserBean;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 * @author honey
 * @date 2023-08-11 03:17:20
 */
public class SpringTest06 {

    public static void main(String[] args) {
        // 从磁盘中读取spring.xml
        FileSystemXmlApplicationContext applicationContext = new FileSystemXmlApplicationContext("F:\\spring.xml");
        // 从IOC容器中读取对象
        UserBean userBean = applicationContext.getBean("userBean", UserBean.class);
        System.out.println(userBean);
    }
}

运行结果

在这里插入图片描述

基于注解方式

  1. @Configuration:配置类
  2. @ComponentScan:扫描指定包中加上了@Controller/@Service/@Reponsitory/@Component等注解的类
  3. @Bean:beanId默认为方法名称
  4. @Import:beanId默认为类的全限定名
    4.1. @Import({A.class,B.class})
    4.2. @Import (MyImportSelector.class),其中MyImportSelector实现了ImportSelector接口
    4.3. @Import (MyImportBeanDefinitionRegistrar.class),其中MyImportBeanDefinitionRegistrar实现了ImportBeanDefinitionRegistrar接口
  5. @Scope:设置作用域(singleton、prototype、request、session)
  6. @Lazy:设置单例对象是否懒加载
  7. @Conditional:根据指定条件判断Bean对象是否加载到IOC容器中

@Import

项目结构

在这里插入图片描述

项目代码

SpringConfig03.java

package com.spring.config;

import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;

/**
 * @author honey
 * @date 2023-08-11 03:53:02
 */
public class SpringConfig03 {

    @Bean
    public UserBean userBean03() {
        return new UserBean();
    }
}

SpringConfig04.java

package com.spring.config;

import com.spring.bean.UserBean;
import org.springframework.context.annotation.Bean;

/**
 * @author honey
 * @date 2023-08-11 03:54:27
 */
public class SpringConfig04 {

    @Bean
    public UserBean userBean04() {
        return new UserBean();
    }
}

MyImportSelector.java

package com.spring.bean;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author honey
 * @date 2023-08-11 03:55:37
 */
public class MyImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.spring.config.SpringConfig04"};
    }
}

MyImportBeanDefinitionRegistrar.java

package com.spring.bean;

import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * @author honey
 * @date 2023-08-11 03:55:45
 */
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(UserBean.class);
        registry.registerBeanDefinition("userBean05", rootBeanDefinition);
    }
}

SpringConfig05.java

package com.spring.config;

import com.spring.bean.MyImportBeanDefinitionRegistrar;
import com.spring.bean.MyImportSelector;
import org.springframework.context.annotation.Import;

/**
 * @author honey
 * @date 2023-08-11 04:02:27
 */
@Import({SpringConfig03.class, MyImportSelector.class, MyImportBeanDefinitionRegistrar.class})
public class SpringConfig05 {

}

SpringTest07.java

package com.spring.test;

import com.spring.bean.UserBean;
import com.spring.config.SpringConfig05;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @author honey
 * @date 2023-08-11 04:06:39
 */
public class SpringTest07 {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig05.class);
        UserBean userBean03 = annotationConfigApplicationContext.getBean("userBean03", UserBean.class);
        System.out.println(userBean03);
        UserBean userBean04 = annotationConfigApplicationContext.getBean("userBean04", UserBean.class);
        System.out.println(userBean04);
        UserBean userBean05 = annotationConfigApplicationContext.getBean("userBean05", UserBean.class);
        System.out.println(userBean05);
    }
}
运行结果

在这里插入图片描述

@Conditional

项目结构

在这里插入图片描述

项目代码

LinuxCondition.java

package com.spring.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * @author honey
 * @date 2023-08-11 04:20:37
 */
public class LinuxCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return System.getProperty("os.name").toLowerCase().contains("linux");
    }
}

WindowsCondition.java

package com.spring.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

/**
 * @author honey
 * @date 2023-08-11 04:22:04
 */
public class WindowsCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return System.getProperty("os.name").toLowerCase().contains("windows");
    }
}

SystemOperation.java

package com.spring.condition;

/**
 * @author honey
 * @date 2023-08-11 04:22:49
 */
public class SystemOperation {

    private final String name;

    public SystemOperation(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "SystemOperation{" +
                "name='" + name + '\'' +
                '}';
    }
}

SpringConfig06.java

package com.spring.config;

import com.spring.condition.LinuxCondition;
import com.spring.condition.SystemOperation;
import com.spring.condition.WindowsCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;

/**
 * @author honey
 * @date 2023-08-11 04:23:27
 */
public class SpringConfig06 {

    @Bean
    @Conditional(value = WindowsCondition.class)
    public SystemOperation windowsSystemOperation() {
        return new SystemOperation("执行windows命令");
    }

    @Bean
    @Conditional(value = LinuxCondition.class)
    public SystemOperation linuxSystemOperation() {
        return new SystemOperation("执行linux命令");
    }
}

SpringTest08.java

package com.spring.test;

import com.spring.condition.SystemOperation;
import com.spring.config.SpringConfig06;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import java.util.Map;

/**
 * @author honey
 * @date 2023-08-11 04:24:39
 */
public class SpringTest08 {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(SpringConfig06.class);
        Map<String, SystemOperation> beansOfType = annotationConfigApplicationContext.getBeansOfType(SystemOperation.class);
        System.out.println(beansOfType);
    }
}
运行结果

在这里插入图片描述

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

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

相关文章

基础实验篇 | QGC实时调整控制器参数实验

PART 1 实验名称及目的 QGC实时调整控制器参数实验&#xff1a;在进行硬件在环仿真和真机实验时&#xff0c;常常需要在QGC地面站中观察飞行状态&#xff0c;并对控制器参数进行实时调整&#xff0c;以使得飞机达到最佳的控制效果&#xff0c;但是&#xff0c;在Simulink中设…

网络编程的一些基础知识

什么是协议 协议就是一种网络交互中数据格式和交互流程的约定,通过协议,我们可以与远程的设备进行数据交互,请求或者完成对方的服务(可以认为协议就是一种语言) 什么是端口和端口监听 在Internet上,各主机间通过TCP/IP协议发送和接收数据包,各个数据包根据其目的主机…

15.3.2 【Linux】系统的配置文件:/etc/crontab,/etc/cron.d/*

这个“ crontab -e ”是针对使用者的 cron 来设计的&#xff0c;如果是“系统的例行性任务”时&#xff0c; 该怎么办呢&#xff1f;是否还是需要以 crontab -e 来管理你的例行性工作调度呢&#xff1f;当然不需要&#xff0c;你只要编辑/etc/crontab 这个文件就可以。有一点需…

防网络钓鱼身份验证是预防违规的关键

全球企业身份验证状况调查结果发现&#xff0c;超过一半的员工依赖不安全的身份验证方法。 Yubico 记录显示&#xff0c;澳大利亚 65% 的员工和新西兰 63% 的员工仍然依赖用户名和密码作为主要身份验证手段&#xff0c;超过了 59% 的全球平均水平。 尽管广泛的宣传活动和企业…

项目实战 — 消息队列(7){虚拟主机设计(1)}

目录 一、什么是虚拟主机 二、编写虚拟主机代码 &#x1f345; 1、准备工作 &#x1f345; 2、实现exchange相关操作 &#x1f384;实现创建交换机exchangeDeclare &#x1f384; 实现 删除交换机exchangeDelete &#x1f345; 3、实现queue相关操作 &#x1f384;实现…

【第二阶段】匿名函数隐式返回函数参数

1.匿名函数简单举例 fun main() {//第一种写法,count()获取字符长度val info"kotlin".count()println(info)//第二种写法&#xff0c;使用匿名函数val len"kotlin".count(){//it代表字符串中 k o t l i n 的字符itl}println(len) }执行结果 2.隐式返回 …

【LeetCode】236. 二叉树的最近公共祖先、 JZ36 二叉搜索树与双向链表

作者&#xff1a;小卢 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 236. 二叉树的最近公共祖先 236. 二叉树的最近公共祖先 题目描述&#xff1a; 给定一个二叉树…

【人工智能前沿弄潮】——生成式AI系列:Diffusers学习(1)了解Pipeline 、模型和scheduler

Diffusers旨在成为一个用户友好且灵活的工具箱&#xff0c;用于构建针对您的用例量身定制的扩散系统。工具箱的核心是模型和scheduler。虽然DiffusionPipeline为了方便起见将这些组件捆绑在一起&#xff0c;但您也可以拆分管道并单独使用模型和scheduler来创建新的扩散系统。 …

MySQL_数据类型

数值类型 类型有符号(SIGNED)取值范围无符号(UNSIGNED)取值范围大小描述TINYINT(-128&#xff0c;127)(0&#xff0c;255)1byte小整数值SMALLINT(-32768&#xff0c;32767)(0&#xff0c;65535)2bytes大整数值INT/INTEGER(-2147483648&#xff0c;2147483647)(0&#xff0c;429…

Redis_持久化(AOF、RDB)

6. Redis AOF 6.1 简介 目前&#xff0c;redis的持久化主要应用AOF&#xff08;Append Only File&#xff09;和RDF两大机制&#xff0c;AOF以日志的形式来记录每个写操作&#xff08;增量保存&#xff09;&#xff0c;将redis执行过的所有指令全部安全记录下来&#xff08;读…

将本地项目上传至gitee的详细步骤

将本地项目上传至gitee的详细步骤 1.在gitee上创建以自己项目名称命名的空项目2.进入想上传的项目的文件夹&#xff0c;然后右键点击3. 初始化本地环境&#xff0c;把该项目变成可被git管理的仓库4.添加该项目下的所有文件5.使用如下命令将文件添加到仓库中去6.将本地代码库与远…

【Node.js】低代码平台源码

一、低代码简介 低代码管理系统是一种通过可视化界面和简化的开发工具&#xff0c;使非专业开发人员能够快速构建和管理应用程序的系统。它提供了一套预先定义的组件和模块&#xff0c;使用户可以通过拖放操作来设计应用程序的界面和逻辑。低代码管理系统还提供了自动化的工作…

IDEA每次启动indexing解决办法

每次启动indexing很浪费时间。 解决办法 setting中搜索index 设置如下&#xff1a; 这样设置以后&#xff0c;启动速度明显快多了。 参考 https://blog.csdn.net/qq_45162113/article/details/121128721

【云原生】Docker 详解(二):Docker 架构及工作原理

Docker 详解&#xff08;二&#xff09;&#xff1a;Docker 架构及工作原理 Docker 在运行时分为 Docker 引擎&#xff08;服务端守护进程&#xff09; 和 客户端工具&#xff0c;我们日常使用各种 docker 命令&#xff0c;其实就是在使用 客户端工具 与 Docker 引擎 进行交互。…

【LangChain概念】了解语言链️:第2部分

一、说明 在LangChain的帮助下创建LLM应用程序可以帮助我们轻松地链接所有内容。LangChain 是一个创新的框架&#xff0c;它正在彻底改变我们开发由语言模型驱动的应用程序的方式。通过结合先进的原则&#xff0c;LangChain正在重新定义通过传统API可以实现的极限。 在上一篇博…

统计学和机器学习之间的联系和区别

一、说明 老实说&#xff0c;我厌倦了几乎每天都在社交媒体和我的大学里听到这场辩论。通常&#xff0c;这伴随着一些模糊的陈述来解释这个问题。双方都为此感到内疚。我希望在本文结束时&#xff0c;您将对这些有些模糊的术语有更明智的立场。 二、论点 与普遍的看法相反&…

SpringCloud源码探析(九)- Sentinel概念及使用

1.概述 在微服务的依赖调用中&#xff0c;若被调用方出现故障&#xff0c;出于自我保护的目的&#xff0c;调用方会主动停止调用&#xff0c;并根据业务需要进行对应处理&#xff0c;这种方式叫做熔断&#xff0c;是微服务的一种保护方式。为了保证服务的高可用性&#xff0c;…

银河麒麟高级操作系统V10助力联通云建设打出组合拳

联通云基于“双引擎基座一云多芯”为不同行业场景提供可靠、高质量的应用上云服务。在核心代码进行了全面把控&#xff0c;定制多架构芯片应用适配模版&#xff0c;开发了计算、存储、网络、中间件等组件&#xff0c;全面适配自主化服务器和操作系统&#xff0c;提供云服务器、…

ffmpeg+intel核显实现硬解码

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、前言二、检查方法1.图形法2.nvidia-smi3.intel-gpu-tools 三、安装使用1.libva-dev2.libva-utils3.编译安装4.测试1.vainfo2.ffmpeg测试解码 总结 前言 之…

微信个人小程序申请 (AppID 和 AppSecret)

1. 登录微信公众平台 https://mp.weixin.qq.com/cgi-bin/loginpage?url%2Fcgi-bin%2Fhome%3Ft%3Dhome%2Findex%26lang%3Dzh_CN%26token%3D47421820 2. 右上角立即注册 3. 注册类型选择小程序 4. 账号信息 5. 邮箱激活 6. 小程序发布流程 7. 小程序信息 (前往填写) 8. 获取小程…