电子商务网站建设合同书,wordpress检验上传的文档,搭建网站需要备案吗,网站流量如何突破众所周知Resource 和 Autowired两大注解是开发中最常用的两大注解。两者有一定的区别#xff1a;
Autowired
Autowired是spring框架提供的注解类#xff0c;默认按照类型进行装配。当在容器中找不到对应类型的bean时会抛出NoSuchBeanDefinitionException异常#xff0c;当…众所周知Resource 和 Autowired两大注解是开发中最常用的两大注解。两者有一定的区别
Autowired
Autowired是spring框架提供的注解类默认按照类型进行装配。当在容器中找不到对应类型的bean时会抛出NoSuchBeanDefinitionException异常当存在多个符合条件的bean且没有指定选择策略时会抛出BeanNotOfRequiredTypeException异常。
Autowired也可以按bean的名称进行装配这个时候需要借助Qualifier注解。
Autowired
Qualifier(injectServiceA)
private InjectService injectService;指定注入的InjectService类型的bean名称为injectServiceA。
Autowired还有一个布尔属性required默认是true如果设置成false找不到对应的依赖不会报错。就需要代码逻辑上来判断是否有当前服务。
Autowired(required false)
private InjectService injectService1;Resource
Resource时Java EE提供的注解规范在 Java EE 容器中同样可以使用。Resource 默认情况下未显示指定bean名称按照名称name进行自动装配。如果按照名称找不到会在尝试按类型进行装配。这样看来Resource相对来说更健壮一些。
Resource注解可以属性和set方法上。使用在属性上就是按属性名进行寻找bean。
Resource
private InjectService otherService;如果要指定名字可以使用name属性
Resource(nameinjectServiceA)
private InjectService injectService2;除了使用name属性也可以使用Qualifier注解指定bean名称。
Resource
Qualifier(injectServiceB)
private InjectService injectService3;也可以指定按类型来装配
Resource(type InjectService.class)
private InjectService injectService4;因为时按照名称进行装配不会存在多个符合条件的bean但是会存在类型不匹配问题抛出BeanNotOfRequiredTypeException异常。
Primary
不管是Resource还是Autowired都存在一个问题按类型查找时候如果存在多个符合条件的bean就无法完成注入这个时候可以在被注入的bean上添加Primary来标识当前bean是多个候选实例中优选选用的bean。找到多个是会优选使用带有Primary注解的bean。
Autowired源码分析
没错Autowired类型的属性注入是通过context初始化时候添加的类后置处理器AutowiredAnnotationBeanPostProcessor来完成的。
在AnnotationConfigApplicationContext容器构造方法初始化reader时候会调用AnnotationConfigUtils.registerAnnotationConfigProcessors来注册processors这里就会加载注解自动注入的bean后置处理器AutowiredAnnotationBeanPostProcessor。
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}AutowiredAnnotationBeanPostProcessor继承自SmartInstantiationAwareBeanPostProcessor。
那么什么时候调用的postProcessor呢在bean的初始化过程中创建完实例后就会进行属性注入主要在 AbstractAutowireCapableBeanFactory#populateBean方法来完成。
//...
PropertyValues pvs (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
boolean hasInstAwareBpps hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck (mbd.getDependencyCheck() ! AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);PropertyDescriptor[] filteredPds null;
if (hasInstAwareBpps) {//是否有InstantiationAwareBeanPostProcessor处理器if (pvs null) {pvs mbd.getPropertyValues();}//逐个拿出InstantiationAwareBeanPostProcessor调用postProcessProperties方法。for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse null) {if (filteredPds null) {filteredPds filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse null) {return;}}pvs pvsToUse;}
}AutowiredAnnotationBeanPostProcessor#postProcessProperties
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {InjectionMetadata metadata findAutowiringMetadata(beanName, bean.getClass(), pvs);metadata.inject(bean, beanName, pvs);return pvs;
}这里首先会根据注解读取所有带有指定注解的bean属性和方法。注解包括Autowired和Value。如果支持JSR-330也包含Inject注解。 这个是在AutowiredAnnotationBeanPostProcessor的构造函数里初始化的。找到带有对应的注解会封装成InjectedElement对象集合放到InjectionMetadata的injectedElements属性里是一个注解。然后metadata.inject方法会将injectedElements一一进行注入调用InjectedElement.inject()方法。
AutowiredFieldElement#inject()主要逻辑
Field field (Field) this.member;
value resolveFieldValue(field, bean, beanName);
if (value ! null) {ReflectionUtils.makeAccessible(field);field.set(bean, value);
}最后会调用beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);方法获取依赖的值这里面就有Autowired注入根据类型的逻辑。将值设置给field完成依赖注入。
Resource注解源码分析
Resource注解的处理过程和Autowired的过程大致是一致的只不过其使用的bean处理器是CommonAnnotationBeanPostProcessor。其找到的符合条件的属性封装成ResourceElement extends LookupElement。获取属性值调用CommonAnnotationBeanPostProcessor.getResourceToInject()方法。
这个就留给自己去看吧。