Spring注解驱动开发系列:
- Spring 组件注册
- Spring Bean的生命周期
- Spring属性赋值
- Spring自动转配
- Spring注解驱动开发之AOP
自动装配
@Autowired
标注在属性、构造器、方法、参数、注解上,自动从容器中寻找相同类型的bean赋值,如果有多个相同类型的,则根据bean的id来匹配。
默认是需要完成装配的,否则报错,当然也可以设置为非必须:@Autowired(required = false)
- 标注在方法上,最常见的就是配置类中结合@Bean和标在set方法上
1 2 3 4 5
| @Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { ...... }
|
标在set方法上时,创建bean后属性初始化过程会调用set方法
- 标注在构造器上
当类中只有一个构造器时,@Autowired可以省略
标注在属性上
标注在注解上,相当于合成注解吧
@Primary
当自动装配,容器中又有多个相同类型的bean,我们想要每次都优先使用某个bean时,可以在那个组件上加上@Primary注解。这样容器就会优先使用这个组件实现自动装配
@Qualifier
如果需要指定需要装配bean的id,则可以@Autowired与@Qualifier配合使用
例如:
1 2 3
| @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
也能实现自动装配,但是需要导入依赖
1 2 3 4 5
| <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
|
是JSR330规范,不属于Spring
和@Autowired一样,先类型再属性id,但是,没有required属性,@Autowired算是@Inject的增强版
Aware接口
当我们想要装配Spring底层的一些Bean时,我们应该实现Aware的对应的子接口

示例:
1 2 3 4 5 6 7 8 9 10 11 12
| @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方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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”)在没有指定环境时,会生效
设置环境的方法:
- 在虚拟机参数位置设置为:-Dspring.profiles.active=test
- 在容器注册启动类前,设置环境变量
1 2 3 4 5 6 7
| AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.getEnvironment().setActiveProfiles("test");
context.register(SpringConfig.class); context.refresh();
|