Cela fait un mois que j'ai implémenté une application utilisant Spring Boot. Cependant, il y a encore beaucoup de parties que je ne comprends pas bien, je vais donc résumer ce que j'ai étudié ici comme un changement de note: v:
Un type d'IoC (Inversion of Control).
Il semble y avoir ServiceLocator
dans IoC, mais veuillez vous référer à ici.
DI est une abréviation pour Dependency Injection, qui est la base de tout Spring. L'explication simple de DI est *** Gestion des instances ***.
--Dans le conteneur DI, créez une nouvelle classe et créez une instance.
Voir ici pour les significations de «dépendance» et «injection» dans DI. Si vous ne comprenez pas le mot «injection de dépendance», vous pouvez le changer en «injecter un objet». DI permet de faire facilement les deux choses ci-dessus en même temps, mais il y en a beaucoup d'autres. : pointer vers le bas:
Au démarrage de Spring, un processus appelé analyse des composants s'exécute et recherche une classe avec les annotations cibles suivantes gérées par DI.
@Component
@Controller
@Service
@Repository
@Configuration
@RestController
@ControllerAdvice
@ManagedBean
@Named
Instanciez et injectez des beans enregistrés dans le conteneur DI. Après avoir collecté les classes cibles DI (Beans), DI crée (de nouvelles) ces instances. Ensuite, l'instance générée est injectée (affectée) par la méthode suivante.
*** - Field injection (obsolète) ***
Pour l'injection de champ, une instance est injectée (assignée) simplement en ajoutant @ Autowired
au champ (variable membre).
@Autowired
private SampleService sampleService;
Cependant, il a été déconseillé en raison des inconvénients suivants ...
Alors maintenant, nous utilisons l'injection de constructeur suivante:
*** ・ Injection constructeur ***
@Service
@Transactional
public class SampleService {
private final SampleRepository sampleRepository;
// spring4.Après 3 quand il y a un constructeur@Le câblage automatique peut être omis
@Autowired
public SampleService(SampleRepository sampleRepository) {
this.sampleRepository = sampleRepository;
}
}
Pour une écriture plus facile, profitez de Lombok.
Annotez simplement @ RequiredArgsConstructor
à la classe: point_down:
@Service
@Transactional
@RequiredArgsConstructor
public class SampleService {
private final SampleRepository sampleRepository;
}
La classe gérée sur le conteneur DI est appelée "Bean".
Fait référence à une classe avec l'annotation @ Component
ou @ Controller
, ou à une classe enregistrée dans le conteneur DI avec la méthode écrite comme @ Bean
.
Tout d'abord, définissez le bean à enregistrer dans le conteneur DI.
JavaConfig.java
@Configuration
public class JavaConfig {
@Bean
public SampleComponent sampleComponent {
return new SampleComponent();
}
@Baan
public SampleController sampleService {
return new SampleService();
}
}
Maintenant, la valeur de retour du getter avec @ Bean
est enregistrée comme Bean du conteneur DI.
Dans JavaConfig, il est nécessaire de préparer des méthodes pour les instances gérées par des conteneurs DI.
Cependant, vous pouvez définir les valeurs à transmettre au constructeur, etc. lors de la création d'une instance, et vous pouvez basculer la classe JavaConfig entre l'environnement de production et l'environnement de développement.
Sur une base d'annotations, Spring enregistre automatiquement les classes avec @ Component
et @ Controller
dans le conteneur DI.
La gestion du cycle de vie est la gestion de la création (nouvelle) et de la destruction des instances. Lorsque vous utilisez un servlet pour créer une application Web, l'instance est enregistrée dans la portée Session ou Request, mais il est nécessaire de savoir exactement quand l'instance sera détruite.
L'étendue de la session et l'étendue de la demande sont les dates d'expiration de l'instance. Les dates d'expiration des deux portées sont différentes comme suit.
La date d'expiration va de la connexion de l'utilisateur à la déconnexion. Par exemple, vous pouvez avoir des informations telles que si l'utilisateur est connecté en tant qu'étendue de session. Le code ci-dessous extrait le code que j'ai utilisé lorsque j'ai créé une application qui utilise OAuth.
OAuthDTO.java
@Data
@Component
@SessionScope
public class OAuthDTO {
private boolean isLogin;
}
Une requête HTTP expire. Par exemple, la plage allant de l'écran de connexion de l'utilisateur à la transition vers l'écran du profil de l'utilisateur en appuyant sur le bouton de connexion est la plage de l'étendue de la requête. Je l'ai utilisé dans l'Interceptor (https://qiita.com/kyabetsuda/items/78a61bfff859fbc9c63f), qui est traité avant l'appel du contrôleur.
OAuthInterceptor.java
@Component
@RequiredArgsConstructor
@RequestScope
public class OAuthInterceptor extends HandlerInterceptorAdapter {
private final OAuthDTO oAuthDTO;
/** {@inheritDoc} */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws AuthenticationException {
if (!oAuthDTO.isLogin()) {
throw new AuthenticationException("Veuillez vous connecter.");
}
return true;
}
}
*** ・ Singleton ***
Créez une seule instance au démarrage de Spring. Après la création, une instance est partagée et utilisée.
En raison du paramètre par défaut, si vous n'ajoutez pas l'annotation @ Scope
, tout sera singleton.
*** · prototype *** Chaque fois que vous obtenez un bean, une instance est créée
*** ・ globalSession *** Des instances sont créées pour chaque session globale dans l'environnement de portlet. Il ne peut être utilisé que pour les applications Web prenant en charge les portlets.
*** ・ application *** Des instances sont créées pour chaque contexte du servlet.
Comme mentionné ci-dessus, vous pouvez facilement créer et détruire une instance en utilisant l'annotation @ Scope
.
@ Component
, les annotations @ Scope
peuvent être utilisées pour @ Bean
et @ Controller
.singleton
Si vous n'ajoutez pas l'annotation @ Scope
, l'instance sera créée avec singleton. Autrement dit, une seule instance de l'objet peut être créée.
Si vous n'êtes pas conscient de la portée, cela peut provoquer des bogues.
@ Controller
, @ Service
et @ Repository
.Par exemple, si une instance de portée singleton a un objet de portée session.
OAuthDTO.java
@Data
@Component
@SessionScope
public class OAuthDTO {
private boolean isLogin;
}
OAuthService.java
@Service
@RequiredArgsConstructor
public class OAuthService {
private final OAuthDTO oAuthDTO;
}
~~ Si cela se produit, le bean (OAuthDTO.java) avec la portée de session passera à la portée singleton. ~~
*** Ajouté le 28 avril *** Je suis désolé. Cette partie était fausse: arc:
@ SessionScope
est disponible depuis le printemps 4.3 et était à l'origine
@Scope(value = “session”, proxyMode = ScopedProxyMode.TARGET_CLASS)
est.
Ainsi, proxyMode = ScopedProxyMode.TARGET_CLASS
est appelé *** Scoped Proxy ***, qui injecte le bean enveloppé dans Proxy, et lorsque vous appelez la méthode du bean injecté, il regarde en fait dans le conteneur DI. La méthode est déléguée au Bean téléchargé.
En d'autres termes ...
Aucun changement de périmètre ne se produit. Actuellement, scoped-proxy
permet de recevoir des choses avec une portée plus étroite que lui du conteneur DI sans se soucier du contrôleur ou de l'intercepteur.
Pour le prototype, etc., il est bon de se référer à ce qui suit.
Cependant, le code de l'exemple ci-dessus n'est pas correct. En injectant OAuthDTO.java dans OAuthService.java, la classe Service a un état. La classe Service n'est pas seulement appelée à partir de la *** classe Controller ***, donc si vous avez un état lié à un contexte spécifique tel qu'une requête HTTP avant la portée, il sera exécuté sur une route qui n'existe pas. Parfois, la question est de savoir où se procurer l'instance.
Par conséquent, dans le code de l'exemple ci-dessus, OAuthDTO.java doit être injecté dans la classe Controller.
Pour la méthode de mise en œuvre réelle, reportez-vous à ce qui suit.
Lombok
Recommended Posts