Spring Core Annotations

Annotations de base de printemps

1. Vue d'ensemble

Nous pouvons tirer parti des capacités du moteur Spring DI en utilisant les annotations des packagesorg.springframework.beans.factory.annotation andorg.springframework.context.annotation.

Nous appelons souvent ces "annotations de base Spring" et nous les examinerons dans ce didacticiel.

2.1. @Autowired

Nous pouvons utiliser les@Autowired àmark a dependency which Spring is going to resolve and inject. Nous pouvons utiliser cette annotation avec un constructeur, un configurateur ou une injection de champ.

Injection constructeur:

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;
    }
}

Injection sur le terrain:

class Car {
    @Autowired
    Engine engine;
}

@Autowired a un argumentboolean appelérequired avec une valeur par défaut detrue. Il ajuste le comportement de Spring lorsqu'il ne trouve pas de grain approprié à câbler. Lorsquetrue, une exception est levée, sinon rien n'est câblé.

Notez que si nous utilisons l'injection de constructeur, tous les arguments de constructeur sont obligatoires.

Depuis la version 4.3, nous n'avons pas besoin d'annoter les constructeurs avec@Autowired explicitement à moins que nous ne déclarions au moins deux constructeurs.

Pour plus de détails, consultez nos articles sur les@Autowired etconstructor injection.

2.2. @Bean

@Bean marque une méthode de fabrique qui instancie un bean Spring:

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

Spring calls these methods lorsqu'une nouvelle instance du type de retour est requise.

Le bean résultant a le même nom que la méthode factory. Si on veut le nommer différemment, on peut le faire avec les argumentsname ouvalue de cette annotation (l'argumentvalue est un alias pour l'argumentname) :

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

Notez que toutes les méthodes annotées avec@Bean doivent être dans les classes@Configuration.

2.3. @Qualifier

Nous utilisons@Qualifier avec@Autowired àprovide the bean id or bean name que nous voulons utiliser dans des situations ambiguës.

Par exemple, les deux beans suivants implémentent la même interface:

class Bike implements Vehicle {}

class Car implements Vehicle {}

Si Spring a besoin d'injecter un beanVehicle, il se retrouve avec plusieurs définitions correspondantes. Dans de tels cas, nous pouvons fournir le nom d'un bean explicitement en utilisant l'annotation@Qualifier.

Utilisation de l'injection de constructeur:

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

Utilisation de l'injection de setter:

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

Alternativement:

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

Utilisation de l'injection sur le terrain:

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

Pour une description plus détaillée, veuillez lirethis article.

2.4. @Required

@Required sur les méthodes de définition pour marquer les dépendances que nous voulons remplir via XML:

@Required
void setColor(String color) {
    this.color = color;
}

    

Sinon,BeanInitializationException sera renvoyé.

2.5. @Value

Nous pouvons utiliser@Value pour injecter des valeurs de propriété dans des beans. Il est compatible avec l'injection de constructeur, de setter et de champ.

Injection constructeur:

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

Setter injection:

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

Alternativement:

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

Injection sur le terrain:

@Value("8")
int cylinderCount;

Bien entendu, l’injection de valeurs statiques n’est pas utile. Par conséquent, nous pouvons utiliserplaceholder strings dans@Value pour câbler les valeursdefined in external sources, par exemple, dans les fichiers.properties ou.yaml.

Supposons le fichier.properties suivant:

engine.fuelType=petrol

Nous pouvons injecter la valeur deengine.fuelType avec ce qui suit:

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

Nous pouvons utiliser@Value même avec SpEL. Des exemples plus avancés peuvent être trouvés dans nosarticle about @Value.

2.6. @DependsOn

Nous pouvons utiliser cette annotation pour créer Springinitialize other beans before the annotated one. Généralement, ce comportement est automatique, basé sur les dépendances explicites entre les beans.

Nous n'avons besoin que de cette annotationwhen the dependencies are implicit, par exemple, le chargement du pilote JDBC ou l'initialisation de la variable statique.

Nous pouvons utiliser@DependsOn sur la classe dépendante en spécifiant les noms des beans de dépendance. L'argumentvalue de l'annotation nécessite un tableau contenant les noms des bean de dépendance:

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

Sinon, si nous définissons un bean avec l'annotation@Bean, la méthode de fabrique doit être annotée avec@DependsOn:

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

2.7. @Lazy

Nous utilisons@Lazy lorsque nous voulons initialiser notre bean paresseusement. Par défaut, Spring crée tous les beans singleton avec impatience au démarrage / au démarrage du contexte de l'application.

Cependant, il existe des cas oùwe need to create a bean when we request it, not at application startup.

Cette annotation se comporte différemment selon l'endroit où nous la plaçons exactement. Nous pouvons le mettre sur:

  • une méthode de fabrique de bean annotée@Bean, pour retarder l'appel de la méthode (d'où la création du bean)

  • une classe @Configuration et toutes les méthodes@Bean contenues seront affectées

  • une classe@Component, qui n'est pas une classe@Configuration, ce bean sera initialisé paresseusement

  • un constructeur, un setter ou un champ@Autowired, pour charger la dépendance elle-même paresseusement (via proxy)

Cette annotation a un argument nommévalue avec la valeur par défaut detrue. Il est utile de remplacer le comportement par défaut.

Par exemple, marquer les beans comme étant chargés avec impatience lorsque le paramètre global est paresseux, ou configurer des méthodes@Bean spécifiques pour un chargement hâtif dans une classe@Configuration marquée avec@Lazy:

@Configuration
@Lazy
class VehicleFactoryConfig {

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

Pour plus d'informations, veuillez visiterthis article.

2.8. @Lookup

Une méthode annotée avec@Lookup indique à Spring de renvoyer une instance du type de retour de la méthode lorsque nous l'appelons.

Informations détaillées sur l'annotationcan be found in this article.

2.9. @Primary

Parfois, nous devons définir plusieurs beans du même type. Dans ces cas, l'injection échouera, car Spring n'a aucune idée de la graine dont nous avons besoin.

Nous avons déjà vu une option pour gérer ce scénario: marquer tous les points de câblage avec@Qualifier et spécifier le nom du bean requis.

Cependant, la plupart du temps, nous avons besoin d'un haricot spécifique et rarement des autres. On peut utiliser@Primary pour simplifier ce cas: siwe mark the most frequently used bean with @Primary il sera choisi sur des points d'injection non qualifiés:

@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;
}

Dans l'exemple précédent,Car est le véhicule principal. Par conséquent, dans la classeDriver, Spring injecte un beanCar. Bien entendu, dans le beanBiker, la valeur du champvehicle sera un objetBike car il est qualifié.

2.10. @Scope

Nous utilisons@Scope pour définir lesscope d'une classe@Component ou d'une définition@Bean. Il peut s'agir desingleton, prototype, request, session, globalSession ou d'une portée personnalisée.

Par exemple:

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

3. Annotations de configuration de contexte

Nous pouvons configurer le contexte d'application avec les annotations décrites dans cette section.

3.1. @Profile

Si nous voulons que Spring soituse a @Component class or a @Bean method only when a specific profile is active, nous pouvons le marquer avec@Profile. On peut configurer le nom du profil avec l'argumentvalue de l'annotation:

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

Vous pouvez en savoir plus sur les profils dansthis article.

3.2. @Import

Nous pouvons utiliserspecific @Configuration classes without component scanning avec cette annotation. Nous pouvons fournir à ces classes l'argumentvalue de@Import:

@Import(VehiclePartSupplier.class)
class VehicleFactoryConfig {}

3.3. @ImportResource

Nous pouvonsimport XML configurations avec cette annotation. Nous pouvons spécifier les emplacements des fichiers XML avec l'argumentlocations, ou avec son alias, l'argumentvalue:

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

3.4. @PropertySource

Avec cette annotation, nous pouvonsdefine property files for application settings:

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

@PropertySource exploite la fonction d'annotations répétées de Java 8, ce qui signifie que nous pouvons marquer une classe avec elle plusieurs fois:

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

3.5. @PropertySources

Nous pouvons utiliser cette annotation pour spécifier plusieurs configurations@PropertySource:

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

Notez que depuis Java 8, nous pouvons obtenir la même chose avec la fonction d’annotation répétée décrite ci-dessus.

4. Conclusion

Dans cet article, nous avons vu un aperçu des annotations de base de Spring les plus courantes. Nous avons vu comment configurer le câblage de bean et le contexte d'application, et comment marquer des classes pour l'analyse de composants.

Comme d'habitude, les exemples sont disponiblesover on GitHub.