Annotations Spring Core

Cet article fait partie d'une série: • Annotations Spring Core (article actuel) • Annotations Spring Web

• Annotations Spring Boot

• Annotations de planification du printemps

• Annotations de données Spring

• Annotations Spring Bean

1. Vue d'ensemble

Nous pouvons exploiter les capacités du moteur Spring DI en utilisant les annotations des packages org.springframework.beans.factory.annotation et org.springframework.context.annotation .

Nous appelons souvent ces «annotations de base Spring» et nous les passerons en revue dans ce didacticiel.

2. Annotations relatives à DI

2.1. @Autowired

Nous pouvons utiliser @Autowired pour marquer une dépendance que Spring va résoudre et injecter . Nous pouvons utiliser cette annotation avec un constructeur, un setter ou une injection de champ.

Injection constructeur:

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

Injection de poseur:

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

Injection sur le terrain:

class Car { @Autowired Engine engine; }

@Autowired a un argument booléen appelé required avec une valeur par défaut de true . Il ajuste le comportement de Spring lorsqu'il ne trouve pas de grain approprié à câbler. Lorsqu'elle est vraie , 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 sauf si nous déclarons au moins deux constructeurs.

Pour plus de détails, consultez nos articles sur @Autowired et l'injection de constructeur.

2.2. @Haricot

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

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

Spring appelle ces méthodes lorsqu'une nouvelle instance du type de retour est requise.

Le bean résultant a le même nom que la méthode de fabrique. Si nous voulons le nommer différemment, nous pouvons le faire avec le nom ou les arguments de valeur de cette annotation (la valeur de l'argument est un alias pour le nom de l'argument ):

@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. @Qualificatif

Nous utilisons @Qualifier avec @Autowired pour fournir l'id ou le nom du bean 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 bean Vehicle , 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 de champ:

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

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

2.4. @Obligatoire

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

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

Sinon, BeanInitializationException sera levée.

2.5. @Valeur

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

Injection de poseur:

@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 sûr, l'injection de valeurs statiques n'est pas utile. , On peut donc utiliser des chaînes espace réservé dans @Value aux valeurs de fil définies dans les sources externes , par exemple, dans .properties ou .yaml fichiers.

Supposons le fichier .properties suivant :

engine.fuelType=petrol

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

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

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

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.

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

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("engine") class Car implements Vehicle {}

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

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

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.

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

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.

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:

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

For further reading, please visit this article.

2.8. @Lookup

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

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

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.

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.

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:

@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.

2.10. @Scope

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.

For example:

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

3. Context Configuration Annotations

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

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:

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

You can read more about profiles in this article.

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:

@Import(VehiclePartSupplier.class) class VehicleFactoryConfig {}

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:

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

3.4. @PropertySource

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

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

@PropertySource exploite la fonction d'annotations répétitives 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 réaliser la même chose avec la fonction d'annotations répétitives comme décrit ci-dessus.

4. Conclusion

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

Comme d'habitude, les exemples sont disponibles à l'adresse over sur GitHub.

Suivant » Annotations Web de printemps