【Spring注解】四、自动装配@Autowired&@Resource
四、自动装配1.@Autowried&@Qualifier和@Primary@Autowried是Spring2.5定义的自动装配的注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 使用 @Autowired的使用来消除 set ,get方法。@Autowired 标注在方法上表示当前方法的自定义参数从容器中赋值,ioc容器默认赋值时,需要调用无参构...
四、自动装配
1.@Autowried&@Qualifier和@Primary
@Autowried是Spring2.5定义的自动装配的注解,它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作。 使用 @Autowired的使用来消除 set ,get方法。@Autowired 标注在方法上表示当前方法的自定义参数从容器中赋值,ioc容器默认赋值时,需要调用无参构造器后,再进行默认赋值,如果当前类只有一个有参的构造器,则@Autwried可以省略,并且该构造器的参数也默认从ioc容器中获取。
我们创建Color接口、以及它的实现类Red和Bule来介绍@Autowried&@Qualifier和@Primary的用法
Color接口
public interface Color {
}
Red实现类
@Component
public class Red implements Color {
public Red() {
System.out.println("这是Red的 构造器");
}
}
Flower类
@Component
public class Flower {
@Autowired
private Color color;
@Override
public String toString() {
return "Folwer{" +"color=" + color +'}';
}
}
配置类 AutowriedConfig
@Configuration
@ComponentScan("com.daxiong.pojo.Autowired")
public class AutowriedConfig {
}
测试类
public class AutowriedConfigTest {
private AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AutowriedConfig.class);
@Test
public void testAutowired1() {
Flower bean = annotationConfigApplicationContext.getBean(Flower.class);
System.out.println(bean);
}
}
此时我们只在Spring容器中注入的一个Color的实现类Red,测试结果
添加Bule类
@Component
public class Bule implements Color {
public Bule() {
System.out.println("这是Bule 的 构造器");
}
}
运行结果:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'flower': Unsatisfied dependency expressed through field 'color'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.daxiong.pojo.Autowired.Color' available: expected single matching bean but found 2: bule,red
.....
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.daxiong.pojo.Autowired.Color' available: expected single matching bean but found 2: bule,red
出现No qualifying bean of type ‘com.daxiong.pojo.Autowired.Color’ available的异常,原因是@Autowried是按照类型注入的,我们在Flower中注入的Color对象没有指定类型,Spring容器不知道到底应该注入哪一个对象的原因。解决办法有以下几种方法:
使用@Qualifier注解,明确的指定注入类型
@Qualifier(value="red") private Color color;
使用@Primary注解,默认指定的类型
@Primary @Component public class Red implements Color { public Red() { System.out.println("这是Red的 构造器"); } }
修改参数名
@Component public class Flower { //修改color的属性名为red @Autowired private Color red; @Override public String toString() { return "Folwer{" +"color=" + red +'}'; }
运行结果:
注意点:
如果在自动装配时。Spring容器中没有注册对应的Bean,就会报错
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.daxiong.pojo.Autowired.Color' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
我们也只需要在@Autowried后加上(required=true)即可
2.@Resource&@Inject
@Resource和@Inject分别是在JSR250和JSR330规范中定义的注解,在Spring中也得到了支持使用方法和@Autowried的类似
@Resource默认是按照属性来装配的,没有支持@Primary和reuired
@Inject支持@Primary,但时不支持reuired,需要导入javax.Inject包
3.Aware注入Spring底层组件&原理
自定义组件想要使用Spring容器底层的一些组件比如ApplicationContext,BeanFactory,等等,都可以通过实现XXXAware,在创建对象时,会把调用接口规定的方法把指定的组件装配进去。
实现原理,这些XXXAware接口,都有对应的XXXprocessor来处理
如ApplicationContextAware有ApplicationContextAwareProcessor来处理Spring源码:
//实现了BeanPostProcessor接口,所以会在组件初始化的识货调用
class ApplicationContextAwareProcessor implements BeanPostProcessor {
//在组件赋值前调用
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
//判断是否为对应接口类型
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
//进行赋值操作
invokeAwareInterfaces(bean);
}
return bean;
}
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);
}
}
}
}
更多推荐
所有评论(0)