2. spring - IOC - 依赖注入

系列篇幅

前言

本文整理一下依赖注入的一些相关文章,

  • @Autowired依赖注入

  • @Primary与@Qualifier

  • @Resource(JSR250规范)

  • @InJect(JSR330规范)

  • @autowired的多种使用方式

    • 构造方法
    • set方法
    • 方法入参
    • 接口方式
  • @Profile

@Autowired依赖注入

public interface Pet {
    void move();
}
@Component
public class Dog implements Pet {

    @Override
    public void move() {
        System.out.println("running");
    }

}
@Data
@Component("person")
public class Person {
    @Value("1")
    private Long id;
    @Value("Jack")
    private String name;
    @Autowired //会根据类名自动查找
    private Pet pet;

    public void call(){
        this.pet.move();
    }
}

Application中使用

@SpringBootApplication
public class FrameworkApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(FrameworkApplication.class, args);
        Person person = ctx.getBean(Person.class);
        person.call();
    }

}

如果我们装配的对象可能不存在,那么需要指定 required = false 否则会抛异常

No qualifying bean of type 'org.example.Pet' available

@Data
@Component("person")
public class Person {
  @Autowired(required=false)
  private Pet pet;
  ...
}

@Primary与@Qualifier

如果存在多个两个实例就会报错

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

@Component
public class Bird implements Pet {
    @Override
    public void move() {
        System.out.println("flying");
    }
}

解决方法(一) @Primary

@Component
@Primary
public class Dog implements Pet {

    @Override
    public void move() {
        System.out.println("running");
    }

}

解决方法(二) @Qualifier

@Data
@Component("person")
public class Person {
  
    ...
    @Autowired
    @Qualifier("dog")
    private Pet pet;

}
@Component
@Qualifier("dog")
public class Dog implements Pet {
  ...
}

@Resource(JSR250规范)

功能和@AutoWired的功能差不多一样,但是不支持@Primary 和@Qualifier的支持

@InJect(JSR330规范)

需要导入jar包依赖,功能和支持@Primary功能 ,但是没有Require=false的功能

 <dependency> 
   <groupId>javax.inject</groupId> 
   <artifactId>javax.inject</artifactId> 
   <version>1</version>
</dependency>

@autowired的多种使用方式

标注在set方法上

//@Autowired
public void setPerson(Person p) {
	this.p = p; 
}

标注在构造方法上

@Data
@Component("person")
public class Person {
  private Pet pet;
  
  @Autowired
	public Person(Pet pet){
    this.pet = pet;
  }
  
}

标注在配置类上的入参中(可以不写)

@Bean
public Person person(@Autowired Pet pet) {
	Person p = new Person(pet);
	return p; 
}

我们自己的组件需要使用spring ioc的底层组件的时候,比如 ApplicationContext等

我们可以通过实现XXXAware接口来实现

@Component
public class TestCompent implements ApplicationContextAware,BeanNameAware {
	private ApplicationContext applicationContext;
  
  @Override
  public void setBeanName(String name) {
     System.out.println("current bean name is :【"+name+"】");
  }
  @Override
  public void setApplicationContext(ApplicationContext applicationContext) 
    throws BeansException {
  	this.applicationContext = applicationContext; 
  }
}

@Profile的使用

作用于效果
类上那么只有当前环境配置,整个配置类才会生效
Bean上只有当前环境的Bean才会被激活
没有标注任何环境都处于激活
@Configuration
// 加载指定的属性文件
@PropertySource(value = {"classpath:test.properties"})
public class MainConfig implements EmbeddedValueResolverAware{

  //pro生产环境激活
	@Profile(value = "pro") 
  public Person proPerson() {
		return new Person("张三"); 
  }
  
	//dev开发环境激活
	@Profile(value = "dev")
  public Person devPerson() {
		return new Person("小红"); 
	}
  
}

激活切换环境的方法

  • 运行JVM的时候通过参数切换

    -Dspring.profiles.active=dev|prod
    
  • 通过代码方式来激活

    public static void main(String[] args) {
      // 1、因为配置类,需重新指定模式(开发或是生产等),所以在新建annotation时,不用加载配置类
      AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
      // 2、使用Environment来指定当前运行的模式,指定的值必须和@Profile注解中自定义的值匹配。否则都不执行。
      ctx.getEnvironment().setActiveProfiles("dev");
      //3、指定模式后,再注册Bean
      ctx.register(MainConfig.class); 
      // //4、刷新容器,注册生效。
      ctx.refresh(); 
      printBeanName(ctx);
    }
    
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页