spring注解源码分析 (spring中源文件注解)

注解说明

Beans on which the current bean depends. Any beans specified are guaranteed to be created by the container before this bean. Used infrequently in cases where a bean does not explicitly depend on another through properties or constructor arguments, but rather depends on the side effects of another bean’s initialization.

指定当前 bean 所依赖的 bean。任何指定的 bean 都保证在当前 bean 之前被容器创建。通过@DependsOn可以调整Bean的创建顺序。

属性说明

	/**
	 * 所依赖的bean的beanName
	 */
	String[] value() default {};

使用示例

@Component
@DependsOn("dependsService")
public class CurrentService {
    public CurrentService () {
        System.out.println("我后被创建");
    }
}

@Component
public class DependsService{
 
    public DependsService() {
        System.out.println("我先被创建");
    }
}

相关源码

AnnotationConfigUtils

	/**
 	* 解析beanDefinition的附加的一些通用注解
 	*/
	static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
		......
		
		// 把DependsOn的value解析为beanDefinition的dependsOn属性
		AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
		if (dependsOn != null) {
			abd.setDependsOn(dependsOn.getStringArray("value"));
		}

		......
	}

AbstractBeanFactory

	protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {

		......

			try {
				//拿到合并后的beanDefinition用于bean的创建
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				// 检查beanDefinition是否合法
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				// 如果有指定依赖,则先初始化这个bean的依赖,通过@Depends注解引入
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						// 如果dep依赖beanName,那就变成相互依赖,直接报异常
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						// 把依赖关系注册起来,进行后续的依赖关系的检查
						registerDependentBean(dep, beanName);
						try {
							// 优先创建被依赖的对象
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

			.......
				
		return (T) bean;
	}