SpringBoot项目定义Bean常见方式

1. spring原生的xml 配置bean 现在几乎淘汰,忽略!!

2. @Component 及其衍生注解 (@Controller、@Service、@Repository)

@Component
public class Cat {
}

3. @Configuration + @Bean

@Configuration
public class AnimalConfig {

    @Bean
    public Dog dog() {
        return new Dog();
    }
}

4. 直接使用@Import

public class Bird {
}

 

  4.1 实现 ImportSelector接口

package com.ldj.springboot.importbean.selector;

import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.CollectionUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;

/**
 * User: ldj
 * Date: 2024/8/24
 * Time: 23:54
 * Description: No Description
 */
public class MyBeanSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        List<String> springBeanPaths = SpringFactoriesLoader.getSpringBeanPaths("spring.factories");
        if (CollectionUtils.isEmpty(springBeanPaths)) {
            throw new RuntimeException("spring.factories文件 缺少配置!");
        }

        // 这个路径数组你也可以直接写,不需要专门读取配置文件,这里是为了演示springboot读取META-INF 里的spring.factories
        return springBeanPaths.toArray(new String[0]);
    }
}

// 读取要注入容器的类所在路径的配置文件
class SpringFactoriesLoader {
    public static List<String> getSpringBeanPaths(String path) {
        List<String> classPaths = new LinkedList<>();
        InputStreamReader inputStreamReader = null;
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        String str;
        try {
            ClassPathResource classPathResource = new ClassPathResource(path);
            inputStream = classPathResource.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream);
            bufferedReader = new BufferedReader(inputStreamReader);
            while ((str = bufferedReader.readLine()) != null) {
                System.out.println(str);
                classPaths.add(str);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (inputStream != null) {
                    inputStream.close();
                }
                if (bufferedReader != null) {
                    bufferedReader.close();
                }
                if (inputStreamReader != null) {
                    inputStreamReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return classPaths;
    }

}

  4.2 实现 ImportBeanDefinitionRegistrar 接口

package com.ldj.springboot.importbean.registrar;

import com.ldj.springboot.importbean.config.OrderConfig;
import com.ldj.springboot.importbean.config.UserConfig;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

/**
 * User: ldj
 * Date: 2024/8/24
 * Time: 22:22
 * Description: No Description
 */
public class MyBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AbstractBeanDefinition userConfigBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(UserConfig.class).getBeanDefinition();
        AbstractBeanDefinition orderConfigBeanDefinition = BeanDefinitionBuilder.genericBeanDefinition(OrderConfig.class).getBeanDefinition();

        // 以定义态方式注册到容器
        registry.registerBeanDefinition("userConfig", userConfigBeanDefinition);
        registry.registerBeanDefinition("orderConfig", orderConfigBeanDefinition);
    }

}
package com.ldj.springboot.importbean;

import com.ldj.springboot.importbean.config.*;
import com.ldj.springboot.importbean.registrar.MyBeanDefinitionRegistrar;
import com.ldj.springboot.importbean.selector.MyBeanSelector;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Import;


@SpringBootApplication
@Import(value = {Bird.class, MyBeanSelector.class, MyBeanDefinitionRegistrar.class,})
public class ImportBeanApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(ImportBeanApplication.class);
        for (String beanDefinitionName : annotationConfigApplicationContext.getBeanDefinitionNames()) {
            System.out.println("beanDefinitionName: " + beanDefinitionName);
        }

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

        // @Component
        System.out.println(annotationConfigApplicationContext.getBean(Cat.class));

        // @Configuration + @Bean
        System.out.println(annotationConfigApplicationContext.getBean(Dog.class));

        // @Import
        System.out.println(annotationConfigApplicationContext.getBean(Bird.class));

        // @Import + ImportSelector
        System.out.println(annotationConfigApplicationContext.getBean(UserConfig.class));
        System.out.println(annotationConfigApplicationContext.getBean(OrderConfig.class));

        //  @Import + ImportBeanDefinitionRegistrar --> (beanDefinition)
        System.out.println(annotationConfigApplicationContext.getBean(ProductConfig.class));
        System.out.println(annotationConfigApplicationContext.getBean(StoreConfig.class));

        // BeanFactoryPostProcessor --> (beanDefinition)
        System.out.println(annotationConfigApplicationContext.getBean("carService"));
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值