【Spring03】Bean的属性赋值和自动注入

Bean的属性赋值和自动注入

一、Bean的属性赋值

Bean的属性赋值可以使用**@Value**,其支持多种方式如下:

1)基本数值

2)可以写SpEL表达式,#{}

3)可以写${},取出配置文件中的值

@Data
public class Property01_Value {

    /**
     * @author  luomengwei
     *  1)基本数值
     *  2)可以写SpEL表达式,#{}
     *  3)可以写${},取出配置文件中的值
     **/
    @Value("wei")
    String name;

    @Value("#{20-2}")
    Integer age;

    @Value("${english.name}")
    String englishName;
}

@PropertySource注解,可以用来读取外部配置文件中的k/v保存到环境变量中。

@PropertySource(value = {"classpath:/propertyvalue.properties"})
//@PropertySources() 多个配置文件
@Configuration
public class Property02_PropertySource {

    @Bean("Property01")
    Property01_Value property01_value() {
        return new Property01_Value();
    }
}

二、Bean的自动注入

2.1 注解自动注入

**@Autowired:**自动注入
1)默认按照类型去容器寻找对应组件:XXXX.class
2)如果找到多个相同类型组件,在按照 属性名 称作为ID去查找
3)@Qualifier(“xxxService2”),使用@Qualifier指定需要装配的组件ID,而不是使用属性名
4)自动装配默认一定需要将属性赋值好,没有就会报错
可以使用 @Autowired(required = false)
5)@Primary标注首选bean 在多个类型组件是,未明确指定组件装配ID时,默认使用首选的bean

Spring还支持 @Resource(JSR250) 和 @Inject(JSR330) JSR:Java规范
**@Resource:**可以和 @Autowired 一样支持自动装配功能,默认按照属性名称进行装配
不支持 Spring的注解指定(@Qualifier),可以使用 @Resource(name = “xxxService2”) 指定组件ID
@Inject:需要导入 javax.inject 的依赖,和 @Autowired 功能一样,但其没有属性,不支持更多的功能如:required = false

那关于 @AutoWire 和 @Resource 的区别是什么呢?
1、@Autowired 是 Spring定义的;@Resource 和 @Inject 是Java规范。

2、依赖查找的顺序是不一样的

​ 依赖注入的功能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到当前类中。查找有分为两种实现:按名称(byName)查找或按类型(byType)查找,其中 @Autowired 和 @Resource 都是既使用了名称查找又使用了类型查找,但二者进行查找的顺序却截然相反。

  • @Autowired 先根据类型(byType)查找,如果存在多个(Bean)再根据名称(byName)进行查找
  • @Resource 先根据名称(byName)查找,如果(根据名称)查找不到,再根据类型(byType)进行查找

3、两者所支持的参数不一样

@Autowired只包含一个参数:required,表示是否开启自动注入,默认是true,要求依赖对象必须存在,如果要允许null值,可以设置为false。

@Resource包含七个参数,其中最重要的两个参数是:name 和 type

4、作用域不同

@Autowired 可以用在方法、构造器、参数、属性;都是从容器中获取参数值

@Resource 只可以使用在field,setter方法上(只能是单个单数的setter方法

2.2 xxxAware注入Spring容器底层组件

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext、BeanFactory、XXX)
自定义组件可实现 xxxAware,在创建对象的时候,调用接口规定的方法注入相关组件: Aware,把Spring底层的组件注入到自定义的bean中
xxxAware,如:ApplicationContextAware、EmbeddedValueResolverAware

@Component
public class AutoWire01_Aware implements ApplicationContextAware, EmbeddedValueResolverAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        String value = resolver.resolveStringValue("你好${os.name},我是EmbeddedValueResolverAware,我的年龄为: #{20-2}");
        System.out.println(value);
    }
}

在【Bean的生命周期及扩展】篇章中有讲解过,@AutoWire和ApplicationContextAware均是依赖于后置处理器 BeanPostProcessor实现的,实现原理可详见该文章。

2.3 @Profile环境切换

@Profile环境切换:指定组件在哪个环境下能被注册到容器中,不指定,任何环境不能注册
1)加了环境标识的bean,只有这个环境被激活时才注册到容器中。默认是:default。
2)注解加在类上,只有是指定环境时,整个配置类里面的配置才生效。

@Configuration
public class AutoWire02_Profile {

    @Profile("default")
    @Bean("defaultSpringPeople")
    SpringPeople defaultSpringPeople() {
        return new SpringPeople("default", 16);
    }

    @Profile("dev")
    @Bean("devSpringPeople")
    SpringPeople devSpringPeople() {
        return new SpringPeople("dev", 18);
    }

    @Profile("test")
    @Bean("testSpringPeople")
    SpringPeople testSpringPeople() {
        return new SpringPeople("test", 20);
    }
}

测试方法:

1、使用命令行参数:在虚拟机参数位置加载 -Dspring.profiles.active=test
2、代码的方式激活某环境

@Test
public void propertyTest() {
    // 默认有参构造器,不能设置参数信息,直接创建了容器
    //AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AutoWire02_Profile.class);
    // 1、创建 applicationContext
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    // 2、设置需要激活的环境
    applicationContext.getEnvironment().setActiveProfiles("test");
    // 3、配置启动类
    applicationContext.register(AutoWire02_Profile.class);
    // 4、启动容器刷新
    applicationContext.refresh();

    String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
    for (String beanDefinitionName : beanDefinitionNames) {
        System.out.println(beanDefinitionName);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值