Spring Core Annotations – Spring核心注解

最后修改: 2018年 6月 7日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

We can leverage the capabilities of Spring DI engine using the annotations in the org.springframework.beans.factory.annotation and org.springframework.context.annotation packages.

我们可以使用org.springframework.beans.factory.annotationorg.springframework.context.annotation包中的注释来利用Spring DI引擎的能力。

We often call these “Spring core annotations” and we’ll review them in this tutorial.

我们通常称这些为 “Spring核心注释”,我们将在本教程中回顾这些注释。

2. DI-Related Annotations

2.与DI相关的注释

2.1. @Autowired

2.1. @Autowired

We can use the @Autowired to mark a dependency which Spring is going to resolve and inject. We can use this annotation with a constructor, setter, or field injection.

我们可以使用@Autowired标记Spring将要解析和注入的依赖关系。我们可以在构造函数、设定器或字段注入中使用这个注解。

Constructor injection:

构造函数注入。

class Car {
    Engine engine;

    @Autowired
    Car(Engine engine) {
        this.engine = engine;
    }
}

Setter injection:

设置者注入。

class Car {
    Engine engine;

    @Autowired
    void setEngine(Engine engine) {
        this.engine = engine;
    }
}

Field injection:

现场注射。

class Car {
    @Autowired
    Engine engine;
}

@Autowired has a boolean argument called required with a default value of true. It tunes Spring’s behavior when it doesn’t find a suitable bean to wire. When true, an exception is thrown, otherwise, nothing is wired.

@Autowired有一个boolean参数,叫做required,默认值为true。当Spring没有找到合适的Bean来连接时,它可以调整Spring的行为。当true时,会抛出一个异常,否则,什么都不会被连接。

Note, that if we use constructor injection, all constructor arguments are mandatory.

注意,如果我们使用构造函数注入,所有构造函数参数都是强制性的。

Starting with version 4.3, we don’t need to annotate constructors with @Autowired explicitly unless we declare at least two constructors.

从4.3版本开始,我们不需要明确地用@Autowired来注释构造函数,除非我们至少声明两个构造函数。

For more details visit our articles about @Autowired and constructor injection.

欲了解更多详情,请访问我们关于@Autowiredconstructor injection的文章。

2.2. @Bean

2.2. @Bean

@Bean marks a factory method which instantiates a Spring bean:

@Bean标志着一个工厂方法,它可以实例化一个Spring Bean。

@Bean
Engine engine() {
    return new Engine();
}

Spring calls these methods when a new instance of the return type is required.

当需要一个返回类型的新实例时,Spring会调用这些方法

The resulting bean has the same name as the factory method. If we want to name it differently, we can do so with the name or the value arguments of this annotation (the argument value is an alias for the argument name):

产生的Bean与工厂方法的名称相同。如果我们想以不同的方式命名它,我们可以通过这个注解的namevalue参数来实现(参数value是参数name的别名)。

@Bean("engine")
Engine getEngine() {
    return new Engine();
}

Note, that all methods annotated with @Bean must be in @Configuration classes.

注意,所有用@Bean注解的方法都必须在@Configuration类中。

2.3. @Qualifier

2.3@Qualify

We use @Qualifier along with @Autowired to provide the bean id or bean name we want to use in ambiguous situations.

我们使用@Qualifier@Autowired提供我们想在模糊情况下使用的bean id或bean name

For example, the following two beans implement the same interface:

例如,以下两个Bean实现了相同的接口。

class Bike implements Vehicle {}

class Car implements Vehicle {}

If Spring needs to inject a Vehicle bean, it ends up with multiple matching definitions. In such cases, we can provide a bean’s name explicitly using the @Qualifier annotation.

如果Spring需要注入一个Vehicle bean,它最终会出现多个匹配定义。在这种情况下,我们可以使用@Qualifier注解明确提供一个Bean的名字。

Using constructor injection:

使用构造函数注入。

@Autowired
Biker(@Qualifier("bike") Vehicle vehicle) {
    this.vehicle = vehicle;
}

Using setter injection:

使用设置器注入。

@Autowired
void setVehicle(@Qualifier("bike") Vehicle vehicle) {
    this.vehicle = vehicle;
}

Alternatively:

或者说。

@Autowired
@Qualifier("bike")
void setVehicle(Vehicle vehicle) {
    this.vehicle = vehicle;
}

Using field injection:

使用现场注射。

@Autowired
@Qualifier("bike")
Vehicle vehicle;

For a more detailed description, please read this article.

如需更详细的描述,请阅读这篇文章

2.4. @Required

2.4.@Required(必填)

@Required on setter methods to mark dependencies that we want to populate through XML:

@Required在setter方法上标记我们想通过XML填充的依赖关系。

@Required
void setColor(String color) {
    this.color = color;
}
<bean class="com.baeldung.annotations.Bike">
    <property name="color" value="green" />
</bean>

Otherwise, BeanInitializationException will be thrown.

否则,BeanInitializationException将被抛出。

2.5. @Value

2.5.@Value

We can use @Value for injecting property values into beans. It’s compatible with constructor, setter, and field injection.

我们可以使用@Value来将属性值注入Bean。它与构造器、设置器和字段注入兼容。

Constructor injection:

构造函数注入。

Engine(@Value("8") int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

Setter injection:

设置者注入。

@Autowired
void setCylinderCount(@Value("8") int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

Alternatively:

或者说。

@Value("8")
void setCylinderCount(int cylinderCount) {
    this.cylinderCount = cylinderCount;
}

Field injection:

现场注射。

@Value("8")
int cylinderCount;

Of course, injecting static values isn’t useful. Therefore, we can use placeholder strings in @Value to wire values defined in external sources, for example, in .properties or .yaml files.

当然,注入静态值是没有用的。因此,我们可以在@Value中使用占位符字符串来连接外部来源中定义的值,例如,在.properties.yaml文件中。

Let’s assume the following .properties file:

让我们假设以下.properties文件。

engine.fuelType=petrol

We can inject the value of engine.fuelType with the following:

我们可以用以下方法注入engine.fuelType的值。

@Value("${engine.fuelType}")
String fuelType;

We can use @Value even with SpEL. More advanced examples can be found in our article about @Value.

我们甚至可以用SpEL来使用@Value。更高级的例子可以在我们的关于@Value文章中找到。

2.6. @DependsOn

2.6.@DependsOn

We can use this annotation to make Spring initialize other beans before the annotated one. Usually, this behavior is automatic, based on the explicit dependencies between beans.

我们可以使用这个注解来使Spring 在被注解的Bean之前初始化其他Bean。通常情况下,这种行为是自动的,基于Bean之间明确的依赖关系。

We only need this annotation when the dependencies are implicit, for example, JDBC driver loading or static variable initialization.

我们只需要这个注解当依赖关系是隐性的,例如JDBC驱动加载或静态变量初始化。

We can use @DependsOn on the dependent class specifying the names of the dependency beans. The annotation’s value argument needs an array containing the dependency bean names:

我们可以在依赖类上使用@DependsOn,指定依赖Bean的名称。该注解的value参数需要一个包含依赖Bean名称的数组。

@DependsOn("engine")
class Car implements Vehicle {}

Alternatively, if we define a bean with the @Bean annotation, the factory method should be annotated with @DependsOn:

另外,如果我们用@Bean注解来定义一个Bean,那么工厂方法应该用@DependsOn来注解。

@Bean
@DependsOn("fuel")
Engine engine() {
    return new Engine();
}

2.7. @Lazy

2.7@Lazy

We use @Lazy when we want to initialize our bean lazily. By default, Spring creates all singleton beans eagerly at the startup/bootstrapping of the application context.

当我们想懒散地初始化Bean时,我们使用@Lazy。默认情况下,Spring会在应用程序上下文的启动/启动时急切地创建所有的单子Bean。

However, there are cases when we need to create a bean when we request it, not at application startup.

然而,在有些情况下,我们需要在请求时创建Bean,而不是在应用程序启动时

This annotation behaves differently depending on where we exactly place it. We can put it on:

这个注解的行为是不同的,取决于我们到底把它放在哪里。我们可以把它放在

  • a @Bean annotated bean factory method, to delay the method call (hence the bean creation)
  • a @Configuration class and all contained @Bean methods will be affected
  • a @Component class, which is not a @Configuration class, this bean will be initialized lazily
  • an @Autowired constructor, setter, or field, to load the dependency itself lazily (via proxy)

This annotation has an argument named value with the default value of true. It is useful to override the default behavior.

该注解有一个名为value的参数,默认值为true。它对于覆盖默认行为很有用。

For example, marking beans to be eagerly loaded when the global setting is lazy, or configure specific @Bean methods to eager loading in a @Configuration class marked with @Lazy:

例如,当全局设置为懒惰时,将Bean标记为急于加载,或者将特定的@Bean方法配置为在@Configuration类中标记为@Lazy的急于加载。

@Configuration
@Lazy
class VehicleFactoryConfig {

    @Bean
    @Lazy(false)
    Engine engine() {
        return new Engine();
    }
}

For further reading, please visit this article.

如需进一步阅读,请访问本文>。

2.8. @Lookup

2.8.@Lookup

A method annotated with @Lookup tells Spring to return an instance of the method’s return type when we invoke it.

@Lookup注解的方法告诉Spring,当我们调用该方法时要返回该方法的返回类型的实例。

Detailed information about the annotation can be found in this article.

关于注释的详细信息可以在这篇文章中找到

2.9. @Primary

2.9.@Primary

Sometimes we need to define multiple beans of the same type. In these cases, the injection will be unsuccessful because Spring has no clue which bean we need.

有时我们需要定义同一类型的多个Bean。在这种情况下,注入将是不成功的,因为Spring不知道我们需要哪种Bean。

We already saw an option to deal with this scenario: marking all the wiring points with @Qualifier and specify the name of the required bean.

我们已经看到一个处理这种情况的选项:用@Qualifier标记所有的接线点,并指定所需Bean的名称。

However, most of the time we need a specific bean and rarely the others. We can use @Primary to simplify this case: if we mark the most frequently used bean with @Primary it will be chosen on unqualified injection points:

然而,大多数时候我们需要一个特定的Bean,而很少需要其他的。我们可以使用@Primary来简化这种情况:如果我们用@Primary标记最常使用的Bean,它将被选择在非限定的注入点上。

@Component
@Primary
class Car implements Vehicle {}

@Component
class Bike implements Vehicle {}

@Component
class Driver {
    @Autowired
    Vehicle vehicle;
}

@Component
class Biker {
    @Autowired
    @Qualifier("bike")
    Vehicle vehicle;
}

In the previous example Car is the primary vehicle. Therefore, in the Driver class, Spring injects a Car bean. Of course, in the Biker bean, the value of the field vehicle will be a Bike object because it’s qualified.

在前面的例子中,Car是主要的交通工具。因此,在Driver类中,Spring注入了一个Car bean。当然,在Biker Bean中,字段vehicle的值将是一个Bike对象,因为它是合格的。

2.10. @Scope

2.10. @范围

We use @Scope to define the scope of a @Component class or a @Bean definition. It can be either singleton, prototype, request, session, globalSession or some custom scope.

我们使用@Scope来定义@Component类或@Bean定义范围它可以是singleton、prototype、request、session、globalSession或一些自定义范围。

For example:

比如说。

@Component
@Scope("prototype")
class Engine {}

3. Context Configuration Annotations

3.上下文配置注释

We can configure the application context with the annotations described in this section.

我们可以用本节描述的注解来配置应用上下文。

3.1. @Profile

3.1. @Profile

If we want Spring to use a @Component class or a @Bean method only when a specific profile is active, we can mark it with @Profile. We can configure the name of the profile with the value argument of the annotation:

如果我们想让Spring只在特定的配置文件激活时使用@Component类或@Bean方法,我们可以用@Profile标记它。我们可以用注解的value参数来配置配置文件的名称。

@Component
@Profile("sportDay")
class Bike implements Vehicle {}

You can read more about profiles in this article.

你可以在这篇文章中阅读更多关于配置文件的信息。

3.2. @Import

3.2@Import

We can use specific @Configuration classes without component scanning with this annotation. We can provide those classes with @Import‘s value argument:

我们可以使用特定的@Configuration类而不需要组件扫描这个注释。我们可以用@Importvalue参数提供这些类。

@Import(VehiclePartSupplier.class)
class VehicleFactoryConfig {}

3.3. @ImportResource

3.3.@ImportResource

We can import XML configurations with this annotation. We can specify the XML file locations with the locations argument, or with its alias, the value argument:

我们可以用这个注释导入XML配置。我们可以用locations参数或其别名value参数指定XML文件位置。

@Configuration
@ImportResource("classpath:/annotations.xml")
class VehicleFactoryConfig {}

3.4. @PropertySource

3.4.@PropertySource

With this annotation, we can define property files for application settings:

有了这个注解,我们可以为应用程序设置定义属性文件

@Configuration
@PropertySource("classpath:/annotations.properties")
class VehicleFactoryConfig {}

@PropertySource leverages the Java 8 repeating annotations feature, which means we can mark a class with it multiple times:

@PropertySource利用了Java 8的重复注释功能,这意味着我们可以用它多次标记一个类。

@Configuration
@PropertySource("classpath:/annotations.properties")
@PropertySource("classpath:/vehicle-factory.properties")
class VehicleFactoryConfig {}

3.5. @PropertySources

3.5.@PropertySources

We can use this annotation to specify multiple @PropertySource configurations:

我们可以使用这个注解来指定多个@PropertySource配置。

@Configuration
@PropertySources({ 
    @PropertySource("classpath:/annotations.properties"),
    @PropertySource("classpath:/vehicle-factory.properties")
})
class VehicleFactoryConfig {}

Note, that since Java 8 we can achieve the same with the repeating annotations feature as described above.

注意,从Java 8开始,我们可以通过上述的重复注解功能实现同样的目的。

4. Conclusion

4.总结

In this article, we saw an overview of the most common Spring core annotations. We saw how to configure bean wiring and application context, and how to mark classes for component scanning.

在这篇文章中,我们看到了最常见的Spring核心注释的概述。我们看到了如何配置Bean wiring和应用上下文,以及如何为组件扫描标记类。

As usual, the examples are available over on GitHub.

像往常一样,这些例子可以在GitHub上找到over

Next »

Spring Web Annotations