Spring自动装配

Spring注解驱动开发系列:

  1. Spring 组件注册
  2. Spring Bean的生命周期
  3. Spring属性赋值
  4. Spring自动转配
  5. Spring注解驱动开发之AOP

自动装配

@Autowired

标注在属性、构造器、方法、参数、注解上,自动从容器中寻找相同类型的bean赋值,如果有多个相同类型的,则根据bean的id来匹配。

默认是需要完成装配的,否则报错,当然也可以设置为非必须:@Autowired(required = false)

  1. 标注在方法上,最常见的就是配置类中结合@Bean和标在set方法上
@Bean
// factory从容器中获取,可以省略@Autowired
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
    ......
}

标在set方法上时,创建bean后属性初始化过程会调用set方法

  1. 标注在构造器上

当类中只有一个构造器时,@Autowired可以省略

  1. 标注在属性上

  2. 标注在注解上,相当于合成注解吧

@Primary

当自动装配,容器中又有多个相同类型的bean,我们想要每次都优先使用某个bean时,可以在那个组件上加上@Primary注解。这样容器就会优先使用这个组件实现自动装配

@Qualifier

如果需要指定需要装配bean的id,则可以@Autowired与@Qualifier配合使用

例如:

@Autowired(required = false)
@Qualifier("userDao2")
private UserDao userDaoImpl;

可以将userDao2的bean注入属性中

当这些注解同时出现时,会优先寻找@Qualifier指定的组件,找不到就报错。

@Resource

是JSR250的,不属于Spring

也能实现自动装配功能,可以指定bean的id(这里相当于@Qualifier的功能),不能指定required,但是有更多别的属性(区别于@Autowired)

默认是优先按照属性名称当作bean的id来装配组件,

找不到时会去寻找同类型的bean,

​ 如果刚好有一个,则装配,

​ 如果没有,则报错

​ 如果有多个,且没有@Primary标注的优先的bean,则报错

​ 如果有多个,但是有@Primary标注的优先的bean,则将其注入

@Inject

也能实现自动装配,但是需要导入依赖

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

是JSR330规范,不属于Spring

和@Autowired一样,先类型再属性id,但是,没有required属性,@Autowired算是@Inject的增强版

Aware接口

当我们想要装配Spring底层的一些Bean时,我们应该实现Aware的对应的子接口

请添加图片描述

示例:

@Component
public class TestAware implements ApplicationContextAware, EmbeddedValueResolverAware {
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println(">>>>>>>>ApplicationContextAware获得》》》"+applicationContext);
    }

    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        System.out.println(">>>>>>>>EmbeddedValueResolverAware获得》》》"+resolver);
        String resolveStringValue = resolver.resolveStringValue("配置文件获取值:${people.name},计算SpEL:#{1+1}");
        System.out.println(resolveStringValue);
    }
}

源码截取分析

在ApplicationContextAwareProcessor中有一个方法完成一部分Aware的注入,在其中就调用了我们自定义Aware子接口实现类的setXxx方法

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof EnvironmentAware) {
            ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
        }
        if (bean instanceof EmbeddedValueResolverAware) {
            ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
        }
        if (bean instanceof ResourceLoaderAware) {
            ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
        }
        if (bean instanceof ApplicationEventPublisherAware) {
            ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
        }
        if (bean instanceof MessageSourceAware) {
            ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
        }
        if (bean instanceof ApplicationContextAware) {
            ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
        }
    }
}

@Profile

标注在(配置)类或者其方法上,让其只有在某个环境中才会生效

例如:@Profile(“test”)标注在注入组件的方法上时,只有当环境为test才会注入容器

注:环境默认为default,@Profile(“default”)在没有指定环境时,会生效

设置环境的方法:

  1. 在虚拟机参数位置设置为:-Dspring.profiles.active=test
  2. 在容器注册启动类前,设置环境变量
// 使用无参构造,避免Spring替我们注册,刷新
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 设置环境变量
context.getEnvironment().setActiveProfiles("test");
// 完成注册、刷新工作
context.register(SpringConfig.class);
context.refresh();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值