Spring注解驱动开发(三) 属性赋值与自动装配

1.属性赋值

@Value

使用 @Value 赋值:

  • 基本数值

  • SpEL,即 #{20-1}

  • ${},取配置文件的值(运行环境)

@PropertySource

只有使用 @PropertySource之后才能使用 @Value

可重复使用,或者使用 @PropertySources

@PropertySource(value = {"classpath:application.properties"}) 
@Component
public class Person {
    @Value("${person.name}")
    public String name;
}
# application.properties
person.name=123

2.自动装配

自动装配: Spring 使用依赖注入(DI),完成对IOC容器中组件依赖完成赋值

@Autowired

自动注入:

  • 优先按类型去容器中查找组件

  • 如果同类型有多个组件,将属性名作为id去容器中查找

  • @Qualifier(id),直接指定id

  • 默认一定能找到组件,并完成装配。可以使用 @Autowired(required=false)使其非必须

  • @Primary,让Spring自动装配时,将其作为首选的bean

生效原理: AutowiredAnnotationBeanPostProcessor进行装配。

@Autowired可以用在构造器,参数,方法,属性上。当作用在方法上时,构建对象时会注入对象并调用该方法

如果只有一个有参构造器或者使用@Bean注解可以省略注解,因为只有这一种初始化方法,只能由容器注入对象。
另外放在参数位置不是很常见。
如:

    Person(Red red){ //只用一个构造器,可省略 @Autowired
        System.out.println("====>"+red);
    }

    Person(@Autowired  Red red){  //用在参数中
        System.out.println("====>"+red);
    }

@Resource & @Inject

@Resource (JSR 250): 效果与 @Autowired 基本相同,默认按组件名称装配,@Primary@Qualifier失效

@Inject (JSR 330): 依赖于javax.inject,效果与 @Autowired 基本相同,require={true|false} 失效

自定义组件使用Spring底层组件

底层组件包括: ApplicationContext,BeanFactory,....
自定义组件实现 xxxAware,会以回调的风格进行注入。使用xxxAwarePostProcesser(后置处理器)实现

public class Red implements ApplicationContextAware {
    ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { //回调的风格进行注入
        this.applicationContext = applicationContext;
    }
}

3.Profile 环境切换

Spring提供的根据当前环境,动态激活和切换组件的功能。

@Profile指定组件在某个环境下被激活。

  • 加了环境标识的bean,只有指定为该环境才能被激活
  • 激活方式
    1. 使用虚拟机参数 -Dspring.profiles.active=dev。类似的使用代码修改Eviroment,具体看下面的代码
    2. 写在配置类上使用 @Profile,配置类不激活的话,配置类中的所有@Bean都失效
 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        ctx.getEnvironment().setActiveProfiles("prod","dev");
        ctx.register(ProfileConfig.class);
        ctx.refresh();
        Arrays.stream(ctx.getBeanDefinitionNames()).forEach(System.out::println);
posted @ 2021-05-27 17:48  Taofoo  阅读(91)  评论(0)    收藏  举报