Bean注册

本文介绍了SpringBoot中四种常用的注解(@Component及其衍生注解),以及如何在第三方对象、配置类管理、导入配置、bean值注入和条件注册等方面的最佳实践。
摘要由CSDN通过智能技术生成

四类常用注解

注解说明位置
@Component声明bean的基础注解不属于以下三类时,用此注解
@Controller@Component的衍生注解标注在控制器类上
@Service@Component的衍生注解标注在业务类上
@Repository@Component的衍生注解标注在数据访问类上(由于与mybatis整合,用的少)

第三方注解

如果要注册的bean对象来自第三方(不是自定义的) 不能使用@Component注解及其衍生注解声明bean需要使用如下注解进行注册

@Bean
原始方式
@SpringBootApplication
public class BootVueApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(BootVueApplication.class, args);
        Country country = context.getBean(Country.class);
        System.out.println(country);
    }

    //注入country对象
    @Bean
    public Country country() {
        return new Country();
    }
}

上述原始方式仅用于了解 在实际开发中考虑到代码的优雅美观性 、

通常将需要注册的第三方对象 放在配置类中统一进行注册

配置类统一管理
@Configuration
public class CommonConfig {

    //注入country对象
    @Bean
    public Country country() {
        return new Country();
    }

    //该注解生成的对象名默认为方法名
    @Bean
	//@Bean("aa") 可以按照实际需要自定义生成的对象名
    //如果方法的内部需要使用到IOC容器中已经存在的bean对象	只需要在方法中声明即可
    public Province province(Country country) {
         System.out.println("province"+country);
        return new Province();
    }
}
@SpringBootApplication
public class BootVueApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(BootVueApplication.class, args);
        //by type
        Country country = context.getBean(Country.class);
        System.out.println(country);

        //by name
        System.out.println(context.getBean("province"));
    }

@Import

导入第三方对象除了上述方式 也可以通过import注解进行导入 这种情况针对于配置类不在启动类所在的包及其子包非常适用

导入配置类
@SpringBootApplication
@Import(CommonConfig.class)
public class BootVueApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(BootVueApplication.class, args);
        //by type
        Country country = context.getBean(Country.class);
        System.out.println(country);

        //by name
        System.out.println(context.getBean("province"));
    }
}

导入多个配置类

在这里插入图片描述

在实际开发中可能配置类不只一个、可以采取数组方式

@Import({CommonConfig.class,CommonConfig.class,CommonConfig.class,CommonConfig.class,CommonConfig.class,})

但是这样带来的结果是代码并不美观此时就可以使用第二种方式

导入 ImportSelector 接口实现类

在这里插入图片描述

这种方式只需要书写配置类的全路径名就可以

public class CommonImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.config.CommonConfig"};
    }
}
@SpringBootApplication
//@Import({CommonConfig.class,CommonConfig.class})
@Import(CommonImportSelector.class)

public class BootVueApplication {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(BootVueApplication.class, args);
        //by type
        Country country = context.getBean(Country.class);
        System.out.println(country);

        //by name
        System.out.println(context.getBean("province"));
    }
}
导入配置类文件信息

一般在实际开发中这种配置类都是以文件形式存在的 因此我们演示一下通过配置文件导入配置类的方式

public class CommonImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//        return new String[]{"com.config.CommonConfig"};
        //开始读取配置文件内容
        List<String> list = new ArrayList<>();
        //获取输入流
        InputStream inputStream = CommonImportSelector.class.getClassLoader().getResourceAsStream("common.imports");
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                list.add(line);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

        }
        return list.toArray(new String[10]);
    }
}
 (IOException e) {
                    throw new RuntimeException(e);
                }
            }

        }
        return list.toArray(new String[10]);
    }
}

bean注册条件

在上述案例中、存在一个问题 注册好的对象并没有具体的值、这样做是没有意义的、接下来我们给要注册的对象赋值。

在配置文件中进行信息配置

country:
  name: china
  sys: local

通过SpringBoot提供的@Value属性获取具体值

    @Bean
    public Country country(@Value("${country.name}") String name,@Value("${country.sys}") String sys) {
        Country country = new Country();
        country.setName(name);
        country.setSys(sys);
        return country;
    }

在这里我们可以看到具体的属性值就获取到了
在这里插入图片描述但如果我们在配置文件中删除了该对象的具体配置信息呢、此时就会出现错误、因为配置文件中的信息不存在
在这里插入图片描述按照正常的需求、应该是在配置文件中存在的进行注入、不存在的不进行注入。基于上述需求我们就得使用SpringBoot提供的注解@Conditional进行条件注册

bean注册条件

以下是@Conditional注解的三个衍生注解
在这里插入图片描述

@ConditionalOnProperty

如果配置文件中配置了该信息则注入没有配置则不注入

    @ConditionalOnProperty(prefix = "country",name={"name","sys"})
    @Bean
    public Country country(@Value("${country.name}") String name,@Value("${country.sys}") String sys) {
        Country country = new Country();
        country.setName(name);
        country.setSys(sys);
        return country;
    }
@ConditionalOnMissingBean

如果IOC容器中不存在Country则注入Province否则不注入

    @ConditionalOnMissingBean(Country.class)
    @Bean
    public Province province() {
        return new Province();
    }
@ConditionalOnClass

只有导入SpringBoot web起步依赖时才注入

  //如果当前环境中存在DispatcherServlet 
    
    @ConditionalOnClass

    @Bean("province1")
    public Province getProvince() {
        return new Province();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值