1. Overview
1.概述
Spring, by default, manages beans’ lifecycle and arranges their initialization order.
默认情况下,Spring管理Bean的生命周期并安排其初始化顺序。
But, we can still customize it based on our needs. We can choose either the SmartLifeCycle interface or the @DependsOn annotation for managing initialization order.
但是,我们仍然可以根据我们的需要对其进行定制。我们可以选择SmartLifeCycle接口或@DependsOn注解来管理初始化顺序。
This tutorial explores the @DependsOn annotation and its behavior in case of a missing bean or circular dependency. Or in case of simply needing one bean initialized before another.
本教程探讨了@DependsOn注解及其在缺少Bean或circular dependency情况下的行为。或者仅仅是在需要一个bean在另一个之前被初始化的情况下。
2. Maven
2.雯雯
First of all, let’s import spring-context dependency in our pom.xml file. We should always refer to Maven Central for the latest version of dependencies:
首先,让我们在pom.xml文件中导入spring-text依赖。我们应该始终参考Maven中心的依赖的最新版本。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
3. @DependsOn
3.@DependsOn
We should use this annotation for specifying bean dependencies. Spring guarantees that the defined beans will be initialized before attempting an initialization of the current bean.
我们应该使用这个注解来指定Bean的依赖性。Spring保证在尝试初始化当前Bean之前,定义的Bean将被初始化。
Let’s say we have a FileProcessor which depends on a FileReader and FileWriter. In this case, FileReader and FileWriter should be initialized before the FileProcessor.
假设我们有一个FileProcessor,它依赖于一个FileReader和FileWriter。在这种情况下,FileReader和FileWriter应该在FileProcessor之前被初始化。
4. Configuration
4.配置
The configuration file is a pure Java class with @Configuration annotation:
配置文件是一个带有@Configuration注解的纯Java类。
@Configuration
@ComponentScan("com.baeldung.dependson")
public class Config {
@Bean
@DependsOn({"fileReader","fileWriter"})
public FileProcessor fileProcessor(){
return new FileProcessor();
}
@Bean("fileReader")
public FileReader fileReader() {
return new FileReader();
}
@Bean("fileWriter")
public FileWriter fileWriter() {
return new FileWriter();
}
}
FileProcessor specifies its dependencies with @DependsOn. We can also annotate a Component with @DependsOn:
FileProcessor用@DependsOn指定其依赖关系。我们也可以用@DependsOn:来注解一个Component。
@Component
@DependsOn({"filereader", "fileWriter"})
public class FileProcessor {}
5. Usage
5.使用方法
Let us create one class File. Each of the beans updates the text within File. FileReader updates it as read. FileWriter updates it as write and FileProcessor updates the text as processed:
让我们创建一个File类。每个Bean都会更新File中的文本。FileReader以读的方式更新它。FileWriter以写的方式更新它,FileProcessor以处理的方式更新文本。
@Test
public void WhenFileProcessorIsCreated_FileTextContains_Processed() {
FileProcessor processor = context.getBean(FileProcessor.class);
assertTrue(processor.process().endsWith("processed"));
}
5.1. Missing Dependency
5.1.缺少依赖性
In case of missing dependency, Spring throws a BeanCreationException with a base exception of NoSuchBeanDefinitionException. Read more about NoSuchBeanDefinitionException here.
如果缺少依赖性,Spring会抛出一个BeanCreationException,其基本异常为NoSuchBeanDefinitionException。请阅读更多关于NoSuchBeanDefinitionException 的信息。
For example, dummyFileProcessor bean depends on a dummyFileWriter bean. Since dummyFileWriter doesn’t exist, it throws BeanCreationException:
例如,dummyFileProcessor bean依赖于dummyFileWriter bean。由于dummyFileWriter不存在,它抛出了BeanCreationException:。
@Test(expected=NoSuchBeanDefinitionException.class)
public void whenDependentBeanNotAvailable_ThrowsNosuchBeanDefinitionException(){
context.getBean("dummyFileProcessor");
}
5.2. Circular Dependency
5.2.循环依赖性
Also, in this case, it throws BeanCreationException and highlights that the beans have a circular dependency:
另外,在这种情况下,它会抛出BeanCreationException ,并强调Bean有一个循环依赖关系。
@Bean("dummyFileProcessorCircular")
@DependsOn({"dummyFileReaderCircular"})
@Lazy
public FileProcessor dummyFileProcessorCircular() {
return new FileProcessor(file);
}
Circular dependencies can happen if a bean has an eventual dependency on itself, creating a circle:
如果一个Bean对自己有最终的依赖,就会发生循环依赖,形成一个循环。
Bean1 -> Bean4 -> Bean6 -> Bean1
6. Key Points
6.关键点
Finally, there are few points which we should take care of while using @DependsOn annotation:
最后,在使用@DependsOn注解时,我们应该注意几个要点。
- While using @DependsOn, we must use component-scanning
- If a DependsOn-annotated class is declared via XML, DependsOn annotation metadata is ignored
7. Conclusion
7.结语
@DependsOn becomes especially useful when building systems with complex dependency requirements.
@DependsOn在构建具有复杂依赖性要求的系统时变得特别有用。
It facilitates the Dependency Injection, ensuring that Spring will have handled all of the initialization of those required Beans before loading our dependent class.
它促进了依赖性注入,确保Spring在加载我们的依赖性类之前已经处理了所有需要的Bean的初始化。
As always, the code can be found over on GitHub.
一如既往,代码可以在GitHub上找到over。