舟山房产网:spring注入bean的几种计谋模式

admin 2个月前 (05-06) 科技 6 0

上篇文章Spring IOC的焦点机制:实例化与注入我们提到在有多个实现类的情况下,spring是若何选择特定的bean将其注入到代码片断中,我们讨论了根据名称注入和使用@Qualifier 注解输入的两种方式,本篇文章将连系之前提到的和spring的其他注入方式一起举行讨论。

本文主题

我们将讨论在一个接口或者抽象类在具有多个实现类的情况下,有若干种计谋能够让我们在特定的代码片断中注入想要的bean。

根据名称

界说一个Skill捏词,他形貌了英雄具备哪些技术,现在有两个英雄的实现类Diana和Irelia,通过component注解将其标注为bean,在容器启动的时刻会将他们加载到容器中。

现在有一个BannerController要使用Diana这个bean

@RestController
public class BannerController {

    @Autowired
    private Skill diana;

    @RequestMapping(value = "/v2/banner", method = {RequestMethod.GET})
    public String test() {
        diana.r();
        return "Hello SpringBoot";
    }
}

private Skill diana;这里将成员变量的名字写成Diana这个bean的名字,容器就会选择Diana这个注入,这就叫做根据名称注入。spring会给每个bean设置默认到的名字也可以自界说,人人自行查找资料领会即可。

@Qualifier 注解

照样上文的例子,若是成员变量名不写成bean的名称,是其他的名字,好比根据通例的写法会写成

private Skill skill;这个时刻就可以使用@Qualifier 注解,

@RestController
public class BannerController {

    @Autowired
    @Qualifier("diana")
    private Skill skill;

    @RequestMapping(value = "/v2/banner", method = {RequestMethod.GET})
    public String test() {
        skill.r();
        return "Hello SpringBoot";
    }

有选择的注入一个bean,注释掉某个bean上的@Component

若是我们确定要使用哪个bean,那可以把其他的注释掉

//@Component
public class Irelia implements Skill {

    public Irelia() {
        System.out.println("Hello, Irelia");
    }
    public void q(){
        System.out.println("Irelia Q");
    }

    public void w(){
        System.out.println("Irelia W");
    }

    public void e(){
        System.out.println("Irelia E");
    }

    public void r(){
        System.out.println("Irelia R");
    }
}

让Skill的实现类只有一个,自然就不要再费心注入哪个了,就只会注入存在于容器当中的惟一的那一个了。

使用@Primary提高bean的优先级

还可以使用@Primary注解提高我们想让注入bean的优先级,那spring在扫描到相同类型的bean的时刻,就会看谁的优先级高,谁高谁注入

@Component
@Primary
public class Diana implements Skill {
    private String skillName = "Diana R";

    public Diana() {
        System.out.println("I am Diana");
    }
    public void q(){
        System.out.println("Diana Q");
    }

    public void w(){
        System.out.println("Diana W");
    }

    public void e(){
        System.out.println("Diana E");
    }

    public void r(){
        System.out.println(this.skillName);
    }
}

然后启动启动程序,接见路由,就会看到下面的输出:

说明确实是注入了Diana这个bean。

阶段总结

上面的实现方式看起来都能实现根据所需注入特定的bean,然则有个问题,当发生转变的时刻,这里的转变可能是英雄名变了,新增英雄或者要替换其他英雄,都需要去手动改代码,有些情况下可能还不只改一处,照样对照繁琐,并不利便。那有没有一种方式可以通过设置文件的形式来指定要注入的bean,当转变发生,只需要改设置,那岂不是很利便很天真很开心。

条件注解

条件注解顾名思义,就是根据条件决议注入哪一个bean,以是要想使用条件注解,就得先写一个条件。

spring为我们提供了特定的方式来实现自己的条件:@Conditional注解+Condition接口,spring的这种方式的原理是把相符条件的bean加加载到容器中,不合的不加载,那这样在注入的时刻就不会有多个相同类型的bean存在了,自然也就注入乐成了。

界说一个类实现Condition接口

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

public class HeroCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  
        return false;
    }
}

实现Condition接口必须实现它的matches方式,我们先来解释一下这个方式的入参和返回值,

ConditionContext是一个接口,界说了他支持那些操作

public interface ConditionContext {
	BeanDefinitionRegistry getRegistry();
	ConfigurableListableBeanFactory getBeanFactory();
	Environment getEnvironment();
	ResourceLoader getResourceLoader();
	ClassLoader getClassLoader();
}

其中的getEnvironment方式会返回Environment工具,他内里会纪录当前应用所有的环境信息,可以通过这个工具获取到我们的设置信息。

返回值是Boolean类型的,哪个bean的条件匹配乐成,就会把这个bean注入到代码片断中去。我们来详细实现一下。

public class HeroCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String name = context.getEnvironment().getProperty("hero.condition");
        System.out.println(name);
        if ("diana".equalsIgnoreCase(name)){
            return true;
        }else if ("irelia".equalsIgnoreCase(name)){
            return true;
        }
        return false;
    }
}
@Configuration
public class HeroConfiguration {
    @Bean
    @Conditional(HeroCondition.class)
    public Skill diana(){
        return new Diana();
    }

    @Bean
    @Conditional(HeroCondition.class)
    public Skill irelia(){
        return new Irelia();
    }
  
}

通过以上的方式,就可以完成一个简朴的条件注解,然则这种需求实在spring boot早已经帮我们实现了,提供了一些注解可以使用,下篇文章我们看看使用spring boot的内置注解,若何来解决我们的问题。

博客地址:https://www.immortalp.com/

迎接人人去 我的博客 瞅瞅,内里有更多关于测试实战的内容哦!!

,

Sunbet

www.tggzfm.com展望2019年,将用完善的服务体系,创新的技术应用,雄厚的资金实力,贴心的服务品质,成为Sunbet会员、代理的首选平台。

皇冠体育声明:该文看法仅代表作者自己,与本平台无关。转载请注明:舟山房产网:spring注入bean的几种计谋模式

标签列表

    文章归档

    站点信息

    • 文章总数:391
    • 页面总数:0
    • 分类总数:8
    • 标签总数:746
    • 评论总数:0
    • 浏览总数:4901