Explication détaillée de 8 cas de type Spring Dependency Injection Bean

1. Objets communs

Il n'y a rien à dire, tout le monde l'utilise de cette façon, par exemple, si vous avez besoin d'utiliser UserService, vous pouvez simplement @Autowired directement.

@Autowired
private UserService userService;

2. Collection et ses sous-interfaces

En plus de prendre en charge l'injection d'un seul objet, @Autowired prend également en charge l'injection d'un objet Collection.

Par exemple, il existe maintenant une interface pour la notification de message MessageNotifier.

Ce type d'interface a généralement différentes implémentations, telles que la notification par e-mail, ou l'application, les SMS, etc., il existe donc de nombreuses implémentations. Si vous avez besoin d'injecter à ce moment, vous pouvez utiliser MessageNotifierla méthode d'injection de Collection, telle que

@Autowired
private List<MessageNotifier> messageNotifiers;

Cependant, il existe une règle dans cette méthode, c'est-à-dire que le type injecté doit être Collection et ses sous-interfaces. Si vous en injectez une directement ArrayList, elle n'est pas prise en charge pour le moment.

3. Tableau

De même, @Autowired peut réaliser la fonction d'injection d'un tableau.

@Autowired
private MessageNotifier[] messageNotifiers;

code afficher comme ci-dessous:

4、Carte

De même, @Autowired peut également injecter une carte.

@Autowired
private Map<String, MessageNotifier> messageNotifierMap;

À ce stade, le type de la carte et de la clé injectées est le nom du bean, qui peut être utilisé en conjonction avec le mode stratégie.

Cependant, cette méthode ne prend en charge que l'injection de l'interface Map et ne prend pas en charge l'interface de sous-type. Le code est le suivant.

5、@Paresseux

Lorsqu'un champ injecté est annoté avec @Lazy, cela signifie que le champ est une injection retardée.

@Autowired
@Lazy
private MessageNotifier messageNotifier;

L'injection retardée ne signifie pas ne pas injecter, mais injecter un objet proxy de type objet cible, le véritable but étant de le créer quand il le faut.

Comme le montre la figure, lorsque MessageNotifierl'annotation @Lazy est ajoutée lors de l'injection, ce qui est injecté à ce moment est en fait MessageNotifierl'objet proxy et l' MessageNotifierobjet réel n'est pas créé. J'appelle l'objet proxy dans la figure MessageNotifierProxy.

Étant donné que l'objet injecté est un objet proxy MessageNotifierProxy, ce qui est réellement utilisé, c'est qu'une fois la méthode MessageNotifierProxyappelée , elle ira dans le conteneur Spring pour trouver l' objet réel, puis appellera la méthode de l'objet.MessageNotifierProxyMessageNotifierProxyMessageNotifierMessageNotifier

code afficher comme ci-dessous:

C'est le principe de l'injection retardée @Lazy. Il ne s'agit pas d'injecter, mais d'injecter un objet proxy, qui peut être compris comme un espace réservé, un shell vide, qui occupe la position en premier, et lorsque le shell est utilisé, le shell trouvera l'objet réel et appellera la méthode du objet réel.

Un scénario d'utilisation de @Lazy consiste à résoudre le scénario de dépendance circulaire que Spring ne peut pas gérer, tel que le scénario de dépendance circulaire utilisant l'annotation @Async

6, facultatif

Facultatif est une API fournie par JDK1.8, qui peut résoudre élégamment le problème du jugement vide.

@Autowired prend également en charge l'injection de types optionnels.

@Autowired
private Optional<MessageNotifier> messageNotifier;

code afficher comme ci-dessous:

Injecting Optional peut résoudre le problème d'anomalie causé par l'inexistence de l'objet injecté, c'est-à-dire l'injection de sécurité.

Par exemple, MessageNotifiercet objet n'existe pas dans le conteneur Spring, s'il est injecté directement, NoSuchBeanDefinitionExceptionune exception sera levée à ce moment.

Ce problème peut être résolu directement en injectant Optional.

En plus de la méthode Facultatif, vous pouvez également définir directement requiredl'attribut de @Autowired sur false pour résoudre le problème que l'objet injecté n'existe pas.

Quel est le rôle de l'existence d'Optionnel ?

En fait, le rôle de Optional est seulement de juger qu'il n'a pas besoin d'être vide, ce qui est aussi le rôle de la classe Optional.Hormis cela, il n'y a pas d'autre différence avec l'objet direct @Autowired.

Injecting Optional n'est pas très pratique, dans mon image, je vois à peine cette injection dans le code source.

7、ObjectFactory 和 ObjectProvider

ObjectFactory et ObjectProvider sont deux interfaces fournies par Spring

ObjectFactory

ObjectProvider hérite d'ObjectFactory

Fournisseur d'objets

@Autowired peut également injecter directement ces deux interfaces.

@Autowired
private ObjectFactory<MessageNotifier> messageNotifierObjectFactory;
@Autowired
private ObjectProvider<MessageNotifier> messageNotifierObjectProvider;

code afficher comme ci-dessous:

On peut également voir à partir de ce code que l'injection finale est en fait DependencyObjectProviderl'implémentation.

ObjectFactory est également utilisé pour les opérations d'injection différée, ce qui est similaire à @Lazy, mais le principe de mise en œuvre est différent.

En utilisant l'exemple ci-dessus, l'objet MessageNotifier n'est pas créé lorsque l'ObjectFactory est injecté.

Lorsque vous devez utiliser MessageNotifier, vous devez l'obtenir via la méthode getObject d'ObjectFactory, puis vous créerez réellement l'objet MessageNotifier.

MessageNotifier messageNotifier = messageNotifierObjectFactory.getObject();

getObject est implémenté comme suit

obtenirObjet

Ainsi, l'exception de dépendance circulaire causée par l'annotation @Async peut être résolue non seulement par l'annotation @Lazy, mais également en injectant ObjectFactory.

De même, ObjectProvider a également la fonction d'injection retardée, mais en plus de l'injection retardée, ObjectProvider fournit en plus la fonction d'injection de sécurité facultative, qu'ObjectFactory n'a pas.

Dans l'exemple ci-dessus, lors de l'utilisation de la méthode getObject de ObjectFactory, si l'objet MessageNotifier n'existe pas dans le conteneur Spring, NoSuchBeanDefinitionExceptionune exception sera également levée à ce moment.

Cependant, la méthode supplémentaire getIfAvailable fournie par ObjectProvider prend en charge la fonction d'obtention d'objets qui n'existent pas. Lorsque l'objet obtenu via getIfAvailable n'existe pas, il renvoie uniquement null et ne lève pas d'exception.

Méthode getIfAvailablegetIfAvailable method

Comparez-le avec l'implémentation de la méthode getObject, c'est-à-dire s'il est nécessaire d'obtenir l'objet lors de l'obtention de l'objet. L'objet obtenu n'est pas nécessaire, de sorte que s'il n'est pas obtenu, une exception ne sera pas levée.

ObjectFactory et ObjectProvider sont beaucoup utilisés dans le framework.

Par exemple, ObjectProvider est largement utilisé lorsque MybatisPlus est automatiquement assemblé

Et le type générique est un tableau ou une collection, ce qui correspond à ce qui a été dit plus haut.

De cette façon, il peut être injecté en toute sécurité.Lorsque le conteneur Spring contient ces objets, MybatisPlus les utilisera et aucune erreur ne sera signalée.

8、Fournisseur JSR-330

Tout d'abord, parlons de ce qu'est le JSR-330.

JSR est l'abréviation de Java Specification Requests, qui est une spécification standard Java.

Et 330 est considéré comme une version, en plus de 330, 250 est plus entendu.

Cette spécification définit certaines annotations IOC. Les annotations bien connues telles que @Resource, @PostConstruct et @PreDestroy sont toutes proposées dans JSR-250.

Certains frameworks IOC implémenteront les fonctions de ces interfaces basées sur cette norme.Par exemple, les frameworks IOC tels que Spring et Dagger2 ont réalisé les fonctions de ces annotations.

Par conséquent, si vous n'utilisez pas le framework Spring et utilisez d'autres frameworks IOC, les annotations @Resource, @PostConstruct et @PreDestroy peuvent toutes prendre effet.

javax.inject.ProviderDans JSR-330, l'interface proposée

Cependant, si vous souhaitez utiliser l'interface JSR-330, vous devez introduire des dépendances

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

Spring prend également en charge l'injection de ce type d'interface

La fonction de cette interface est la même que celle de l'ObjectFactory mentionnée précédemment, et elle prend également en charge la fonction d'injection retardée.

Résumer

Jusqu'à présent, les 8 types de beans que Spring peut injecter sont terminés. En fait, ces 8 types peuvent être divisés selon les fonctions suivantes :

  • L'injection unique consiste à injecter un seul objet

  • Injection de collection, qui peut injecter des tableaux ou des collections

  • Injection retardée, telle que @Lazy, ObjectFactory, ObjectProvider, JSR-330 Provider

  • Injection sécurisée, s'il n'y a pas d'exception, aucune exception ne sera levée, comme Facultatif, ObjectProvider

Ces méthodes ne sont pas mutuellement exclusives, par exemple, l'injection différée peut également injecter une collection, l'utilisation d'ObjectProvider dans l'assemblage automatique de MyBaisPlus mentionné précédemment en est un bon exemple.

Dans le même temps, bien que cet article illustre la méthode d'annotation et d'injection de champ @Autowird, le type de bean injecté mentionné ci-dessus n'a rien à voir avec la méthode d'annotation et d'injection. L'annotation @Resource, l'injection de constructeur et l'injection de setter sont toutes identiques.

Je suppose que tu aimes

Origine blog.csdn.net/agonie201218/article/details/131685354
conseillé
Classement