对于最新的稳定版本,请使用 Spring Framework 7.0.6!spring-doc.cadn.net.cn

使用 @Autowired

JSR 330 的 @Inject 注解可以用于替代本节示例中的 Spring 的 @Autowired 注解。有关更多详细信息,请参见 这里spring-doc.cadn.net.cn

您可以将 @Autowired 注解应用于构造函数,如下例所示:spring-doc.cadn.net.cn

public class MovieRecommender {

	private final CustomerPreferenceDao customerPreferenceDao;

	@Autowired
	public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
		this.customerPreferenceDao = customerPreferenceDao;
	}

	// ...
}
class MovieRecommender @Autowired constructor(
	private val customerPreferenceDao: CustomerPreferenceDao)

从Spring Framework 4.3开始,如果目标bean最初只定义了一个构造函数,则不再需要在该构造函数上使用@Autowired注解。但是,如果有多个构造函数可用且没有主/默认构造函数,则必须至少有一个构造函数使用@Autowired进行注解,以指示容器使用哪一个。有关详细信息,请参阅关于构造函数解析的讨论。spring-doc.cadn.net.cn

你也可以将 @Autowired 注解应用于 传统 的 setter 方法, 如下面的示例所示:spring-doc.cadn.net.cn

public class SimpleMovieLister {

	private MovieFinder movieFinder;

	@Autowired
	public void setMovieFinder(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}

	// ...
}
class SimpleMovieLister {

	@set:Autowired
	lateinit var movieFinder: MovieFinder

	// ...

}

你也可以将注解应用于任意名称和多个参数的方法,如下例所示:spring-doc.cadn.net.cn

public class MovieRecommender {

	private MovieCatalog movieCatalog;

	private CustomerPreferenceDao customerPreferenceDao;

	@Autowired
	public void prepare(MovieCatalog movieCatalog,
			CustomerPreferenceDao customerPreferenceDao) {
		this.movieCatalog = movieCatalog;
		this.customerPreferenceDao = customerPreferenceDao;
	}

	// ...
}
class MovieRecommender {

	private lateinit var movieCatalog: MovieCatalog

	private lateinit var customerPreferenceDao: CustomerPreferenceDao

	@Autowired
	fun prepare(movieCatalog: MovieCatalog,
				customerPreferenceDao: CustomerPreferenceDao) {
		this.movieCatalog = movieCatalog
		this.customerPreferenceDao = customerPreferenceDao
	}

	// ...
}

您可以将 @Autowired 应用于字段,甚至可以将其与构造函数结合使用,如下例所示:spring-doc.cadn.net.cn

public class MovieRecommender {

	private final CustomerPreferenceDao customerPreferenceDao;

	@Autowired
	private MovieCatalog movieCatalog;

	@Autowired
	public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
		this.customerPreferenceDao = customerPreferenceDao;
	}

	// ...
}
class MovieRecommender @Autowired constructor(
	private val customerPreferenceDao: CustomerPreferenceDao) {

	@Autowired
	private lateinit var movieCatalog: MovieCatalog

	// ...
}

确保您的目标组件(例如,MovieCatalogCustomerPreferenceDao)通过您用于 @Autowired 注解的注入点的类型进行一致声明。否则,可能会由于运行时出现“未找到类型匹配”错误而导致注入失败。spring-doc.cadn.net.cn

对于通过类路径扫描找到的XML定义的bean或组件类,容器通常会提前知道具体的类型。但是,对于@Bean工厂方法,您需要确保声明的返回类型足够明确。对于实现多个接口的组件,或者可能通过其实现类型引用的组件,请考虑在您的工厂方法中声明最具体的返回类型(至少要满足引用您的bean的注入点的要求)。spring-doc.cadn.net.cn

您还可以通过将 @Autowired 注解添加到期望该类型数组的字段或方法上来指示 Spring 从 ApplicationContext 提供该类型的全部 beans,如下例所示:spring-doc.cadn.net.cn

public class MovieRecommender {

	@Autowired
	private MovieCatalog[] movieCatalogs;

	// ...
}
class MovieRecommender {

	@Autowired
	private lateinit var movieCatalogs: Array<MovieCatalog>

	// ...
}

类型集合也适用此规则,如下例所示:spring-doc.cadn.net.cn

public class MovieRecommender {

	private Set<MovieCatalog> movieCatalogs;

	@Autowired
	public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
		this.movieCatalogs = movieCatalogs;
	}

	// ...
}
class MovieRecommender {

	@Autowired
	lateinit var movieCatalogs: Set<MovieCatalog>

	// ...
}

您的目标Bean可以实现org.springframework.core.Ordered接口,或者如果希望数组或列表中的项按特定顺序排序,可以使用@Order或标准的@Priority注解。否则,它们的顺序将遵循容器中相应目标Bean定义的注册顺序。spring-doc.cadn.net.cn

您可以将 @Order 注解声明在目标类级别和 @Bean 方法上, 可能用于单独的 bean 定义(当多个定义使用相同的 bean 类时)。 @Order 值可能会影响注入点的优先级, 但请注意,它们不会影响单例的启动顺序,这是一个由依赖关系和 @DependsOn 声明决定的独立问题。spring-doc.cadn.net.cn

请注意,标准的 jakarta.annotation.Priority 注解在 @Bean 层级不可用,因为不能在方法上声明它。其语义可以通过 @Order 值与 @Primary 在每个类型的一个 bean 上结合使用来建模。spring-doc.cadn.net.cn

即使类型为 Map 的实例也可以自动注入,只要预期的键类型是 String。 映射值包含所有预期类型的 beans,而键包含相应的 bean 名称,如下例所示:spring-doc.cadn.net.cn

public class MovieRecommender {

	private Map<String, MovieCatalog> movieCatalogs;

	@Autowired
	public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
		this.movieCatalogs = movieCatalogs;
	}

	// ...
}
class MovieRecommender {

	@Autowired
	lateinit var movieCatalogs: Map<String, MovieCatalog>

	// ...
}

默认情况下,当没有可用的匹配候选 Bean 时,自动装配会失败。在声明了数组、集合或映射的情况下,至少需要一个匹配的元素。spring-doc.cadn.net.cn

默认行为是将带注解的方法和字段视为指示必需的依赖项。您可以按照以下示例中的方法更改此行为,使框架通过将其标记为非必需来跳过无法满足的注入点(即,通过将 required 属性设置为 @Autowiredfalse):spring-doc.cadn.net.cn

public class SimpleMovieLister {

	private MovieFinder movieFinder;

	@Autowired(required = false)
	public void setMovieFinder(MovieFinder movieFinder) {
		this.movieFinder = movieFinder;
	}

	// ...
}
class SimpleMovieLister {

	@Autowired(required = false)
	var movieFinder: MovieFinder? = null

	// ...
}

如果其依赖项(或在多个参数的情况下,其中一个依赖项)不可用,则不会调用非必需方法。在这种情况下,非必需字段将不会被填充,保留其默认值。spring-doc.cadn.net.cn

换句话说,将 required 属性设置为 false 表示该属性在自动连线时是可选的,如果无法自动连线,则该属性将被忽略。这允许属性被赋予默认值,这些值可以通过依赖注入进行可选的覆盖。spring-doc.cadn.net.cn

注入的构造函数和工厂方法参数是一个特殊情况,因为 required 属性在 @Autowired 中由于 Spring 的构造函数解析算法可能涉及多个构造函数,因此含义略有不同。构造函数和工厂方法参数默认是必需的,但在单个构造函数的情况下有一些特殊规则,例如多元素注入点(数组、集合、映射)如果没有匹配的 bean 可用,会解析为空实例。这允许一种常见的实现模式,即所有依赖项都可以在唯一的多参数构造函数中声明——例如,声明为一个没有 @Autowired 注解的公共构造函数。spring-doc.cadn.net.cn

任何给定的bean类只能有一个构造函数声明@Autowired,并且将required属性设置为true,这表示在用作Spring bean时要自动注入的构造函数。因此,如果required属性保持其默认值true,则只能有一个构造函数使用@Autowired进行注解。如果多个构造函数声明了该注解,则它们都必须声明required=false,以便作为自动注入的候选(类似于XML中的autowire=constructor)。具有最多可由Spring容器中的匹配bean满足的依赖项的构造函数将被选择。如果没有任何候选构造函数可以满足,则将使用主/默认构造函数(如果存在的话)。同样,如果一个类声明了多个构造函数但没有一个使用@Autowired进行注解,则将使用主/默认构造函数(如果存在的话)。如果一个类只声明了一个构造函数,则无论是否进行注解都会使用它。请注意,带注解的构造函数不一定是公共的。spring-doc.cadn.net.cn

或者,您可以通过 Java 8 的 java.util.Optional 表达特定依赖项的非必需性,如下例所示:spring-doc.cadn.net.cn

public class SimpleMovieLister {

	@Autowired
	public void setMovieFinder(Optional<MovieFinder> movieFinder) {
		...
	}
}

从Spring框架5.0开始,您还可以使用@Nullable注解(任何类型的任何包中的注解 — 例如,来自JSR-305的javax.annotation.Nullable),或者直接利用Kotlin内置的空安全支持:spring-doc.cadn.net.cn

public class SimpleMovieLister {

	@Autowired
	public void setMovieFinder(@Nullable MovieFinder movieFinder) {
		...
	}
}
class SimpleMovieLister {

	@Autowired
	var movieFinder: MovieFinder? = null

	// ...
}

您也可以使用 @Autowired 来表示那些已知的可解析依赖接口: BeanFactoryApplicationContextEnvironmentResourceLoaderApplicationEventPublisherMessageSource。这些接口及其扩展接口, 例如 ConfigurableApplicationContextResourcePatternResolver,会自动被解析,无需特殊配置。 下面的示例演示了如何自动注入一个 ApplicationContext 对象:spring-doc.cadn.net.cn

public class MovieRecommender {

	@Autowired
	private ApplicationContext context;

	public MovieRecommender() {
	}

	// ...
}
class MovieRecommender {

	@Autowired
	lateinit var context: ApplicationContext

	// ...
}

Spring 的 @Autowired@Inject@Value@Resource 注解由 BeanPostProcessor 实现处理。这意味着您不能在自己的 BeanPostProcessorBeanFactoryPostProcessor 类型(如果有)中使用这些注解。 这些类型必须通过 XML 或 Spring @Bean 方法显式“连接”。spring-doc.cadn.net.cn