扫描下方二维码或者微信搜索公众号
菜鸟飞呀飞
,便可关注微信公众号,阅读更多Spring源码分析和Java并发编程文章。java
在平时工做中,只要是作Java开发,基本都离不开Spring框架,Spring的一大核心功能就是IOC,它能帮助咱们实现自动装配,基本上天天咱们都会使用到@Autowired注解来为咱们自动装配属性,那么你知道Autowired注解的原理吗?在阅读本文以前,能够先思考一下如下几个问题。spring
先按照以下示例搭建一下本文的demo工程sql
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
复制代码
@Configuration
@ComponentScan("com.tiantang.study")
public class AppConfig {
}
复制代码
public interface UserService {
}
复制代码
@Service
public class UserServiceImpl implements UserService {
}
复制代码
public interface OrderService {
void query();
}
复制代码
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private UserService userService;
public void query(){
System.out.println(userService);
}
}
复制代码
public class MainApplication {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = applicationContext.getBean(OrderService.class);
orderService.query();
}
}
复制代码
经过上面的demo咱们完成了对OrderServiceImpl的自动装配,为其属性userService完成了赋值操做,那么Spring是如何经过@Autowired来实现赋值的呢?咱们知道,Spring在容器启动阶段,会先实例化bean,而后再对bean进行初始化操做。在初始化阶段,会经过调用Bean后置处理来完成对属性的赋值等操做,那么同理,要想实现@Autowired的功能,确定也是经过后置处理器来完成的。这个后置处理器就是AutowiredAnnotationBeanPostProcessor。接下来咱们就来看看这个类的源码。编程
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class)
启动容器的时候,在构造方法中会调用到this()
方法,在this()
方法中最终会调用到registerAnnotationConfigProcessors()
方法,在该方法中,Spring会向容器注册7个Spring内置的Bean,其中就包括AutowiredAnnotationBeanPostProcessor。若是想详细了解Spring容器的启动过程,能够参考笔者的另外一篇文章:Spring源码系列之容器启动流程public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) {
// 省略部分代码...
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 注册AutowiredAnnotationBeanPostProcessor,这个bean的后置处理器用来处理@Autowired的注入
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));
}
// 注册CommonAnnotationBeanPostProcessor,用来处理如@Resource等符合JSR-250规范的注解
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
return beanDefs;
}
复制代码
AutowiredAnnotationBeanPostProcessor是什么时候被调用的呢?数组
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 执行后置处理器,填充属性,完成自动装配
// 在这里会调用到AutowiredAnnotationBeanPostProcessor
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
}
}
复制代码
public PropertyValues postProcessPropertyValues( PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
// 解析出bean中带有@Autowired注解、@Inject和@Value注解的属性和方法
// 对于本文的demo而言,在此处就会解析出OrderServiceImpl类上的userService属性
// 至于如何解析的,findAutowiringMetadata()方法比较复杂,这里就不展开了,Spring中提供了不少对注解等元数据信息读取的方法,进行了大量的封装。
// 若是不是本身亲自参与开发Spring的话,很难摸透它封装的那些数据结构。
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 自动装配,实现依赖注入
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
复制代码
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
复制代码
public AutowiredAnnotationBeanPostProcessor() {
// 添加@Autowired
this.autowiredAnnotationTypes.add(Autowired.class);
// 添加@Value
this.autowiredAnnotationTypes.add(Value.class);
try {
// 若是项目中引入了JSR-330相关的jar包,那么就会添加@Inject
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
}
}
复制代码
beanFactory.resolveDependency()
。protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 判断缓存(第一次注入userService的时候,确定没有缓存,因此会进入到else里面)
// 当第一次注入完成后,会将userService缓存到cachedFieldValue这个属性中,
// 这样当其余的类一样须要注入userService时,就会从这儿的缓存当中读取了。
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 经过beanFactory.resolveDependency()方法,来从容器中找到userService属性对应的值。
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
// 省略部分代码...
// 省略的这部分代码就是将value进行缓存,缓存到cachedFieldValue属性中
}
if (value != null) {
// 经过Java的反射,为属性进行复制
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
复制代码
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
// 省略部分不重要的代码...
// 属性的类型多是数组、集合、Map类型,因此这一步是处理数组类型、Collection、Map类型的属性
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
// 根据须要注入的类型type,从容器中找到有哪些匹配的Bean。
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
// 若是从容器中没有找到,且@Autowired的required属性为true,那么则会抛出异常
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
// 先根据类型匹配出能够依赖注入的bean的Class,若是匹配出多个,则再根据属性名匹配
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
// 当匹配到多个bean的Class,可是殊不知道要选择哪个注入时,就会抛出异常
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
// We have exactly one match.
// 只匹配到一个,则就使用匹配到这个类型
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
// 此处instanceCandidate = UserServiceImpl.class
if (instanceCandidate instanceof Class) {
// instanceCandidate是注入属性的类型,这个须要根据Class,经过FactoryBean的getBean()方法,建立该类型的单例bean
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
// 若是没从容器中找到对应的bean,则须要判断属性值是不是必须注入的,
// 即@Autowired(required=false/true),若是为true,则抛异常,这就是常常项目启动时,咱们看到的异常
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
复制代码
@Autowired
private UserService[] userServiceArray;
@Autowired
private List<UserService> userServiceList;
@Autowired
private Map<String,UserService> userServiceMap;
复制代码
private Object resolveMultipleBeans(DependencyDescriptor descriptor, @Nullable String beanName, @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) {
Class<?> type = descriptor.getDependencyType();
// 处理数组类型
if (type.isArray()) {
// findAutowireCandidates最终会调用getBean()方法
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
return result;
}
// 处理集合类型
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
// findAutowireCandidates最终会调用getBean()方法
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
return result;
}
// 处理Map类型
else if (Map.class == type) {
// findAutowireCandidates最终会调用getBean()方法
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
return matchingBeans;
}
else {
return null;
}
}
复制代码
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
复制代码
NoSuchBeanDefinitionException
。// 若是容器汇总没有找到指定类型的bean,那么matchingBeans属性就是空的
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
// 抛出异常
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
复制代码
if (matchingBeans.size() > 1) {
// 判断应该使用哪个bean
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
// 当匹配到多个bean的Class,可是殊不知道要选择哪个注入时,就会抛出异常
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
复制代码
NoUniqueBeanDefinitionException
。"expected single matching bean but found " + beanNamesFound.size() + ": " + StringUtils.collectionToCommaDelimitedString(beanNamesFound)
复制代码
NoUniqueBeanDefinitionException
异常。这就是咱们日常所说的@Autowired注解是先根据类型注入,当碰到多个相同类型时,就会根据属性名注入。它的实现原理就是在以下代码中实现的。
protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
Class<?> requiredType = descriptor.getDependencyType();
// 根据Primary注解来决定优先注入哪一个bean
String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
if (primaryCandidate != null) {
return primaryCandidate;
}
// 根据@Priority注解的优先级来决定注入哪一个bean
String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
if (priorityCandidate != null) {
return priorityCandidate;
}
// 若是既没有指定@Primary,也没有指定@Priority,那么就会根据属性的名称来决定注入哪一个bean
// 若是要注入的属性的名称与Bean的beanName相同或者别名相同,那么会就会优先注入这个Bean
for (Map.Entry<String, Object> entry : candidates.entrySet()) {
String candidateName = entry.getKey();
Object beanInstance = entry.getValue();
if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
matchesBeanName(candidateName, descriptor.getDependencyName())) {
return candidateName;
}
}
// 前面三种状况都没有肯定要注入哪一个bean,那么就返回null。当返回null时,那么就会再调用该方法出抛出异常。
return null;
}
复制代码
AutowiredFeildElement.inject()
方法中,经过反射进行注入,完成自动装配。在文章的开头,我问了一个问题:自动装配的模型是什么?有哪几种?和Autowired注解有什么关联?实际上这个问题,和今天的主角AutowiredAnnotationBeanPostProcessor没有任何关系。可是为何又把它放在这篇文章中提出来呢?这是由于@Autowired注解的实现原理和自动装配模型极为容易混淆。缓存
public enum Autowire {
NO(AutowireCapableBeanFactory.AUTOWIRE_NO),
BY_NAME(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME),
BY_TYPE(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
}
复制代码
<bean id="orderService" class="com.tiantang.study.service.impl.OrderServiceImpl" autowire="byName">
</bean>
复制代码
@Bean(autowire = Autowire.BY_NAME)
public OrderService orderService(){
return new OrderServiceImpl();
}
复制代码
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 判断bean的注入模型是byName,仍是byType。
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 对于MyBatis而言,Mapper在实例化以后,会填充属性,这个时候,须要找到MapperFactoryBean有哪些属性须要填充
// 在Mapper的BeanDefinition初始化时,默认添加了一个属性,addToConfig
// 在下面的if逻辑中,执行完autowireByType()方法后,会找出另外另个须要填充的属性,分别是sqlSessionFactory和sqlSessionTemplate
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 第六次执行后置处理器,填充属性,完成自动装配
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
// 实现经过byName或者byType类型的属性注入
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
复制代码
// 判断bean的注入模型是byName,仍是byType。
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 对于MyBatis而言,Mapper在实例化以后,会填充属性,这个时候,须要找到MapperFactoryBean有哪些属性须要填充
// 在Mapper的BeanDefinition初始化时,默认添加了一个属性,addToConfig
// 在下面的if逻辑中,执行完autowireByType()方法后,会找出另外另个须要填充的属性,分别是sqlSessionFactory和sqlSessionTemplate
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
复制代码
applyPropertyValues()
方法,而后将其填充到Bean当中。sqlSessionFactory
、sqlSessionTemplate
,而后为这两个属性赋值。private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
GenericBeanDefinition definition;
for (BeanDefinitionHolder holder : beanDefinitions) {
definition = (GenericBeanDefinition) holder.getBeanDefinition();
// 指定MapperFactoryBean的自动装配模型为AUTOWIRE_BY_TYPE
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
}
}
复制代码
总结以前,先回答一下文章开头的三个问题。1)@Autowired注解的实现是经过后置处理器AutowiredAnnotationBeanPostProcessor类的postProcessPropertyValues()方法实现的。2)当自动装配时,从容器中若是发现有多个同类型的属性时,@Autowired注解会先根据类型判断,而后根据@Primary、@Priority注解判断,最后根据属性名与beanName是否相等来判断,若是仍是不能决定注入哪个bean时,就会抛出NoUniqueBeanDefinitionException异常。3)@Autowired自动装配中byName、byType与自动装配的模型中的byName、byTYpe没有任何关系,二者含义彻底不同,前者是实现技术的手段,后者是用来定义BeanDefiniton中autowireMode属性的值的类型。微信
相关推荐数据结构