Maison > Java > javaDidacticiel > Quel est le principe sous-jacent de SpringBoot ?

Quel est le principe sous-jacent de SpringBoot ?

王林
Libérer: 2023-05-11 12:40:06
avant
814 Les gens l'ont consulté

Springboot manuscrit

Dans le développement quotidien, il vous suffit d'introduire les dépendances suivantes pour développer un servlet d'accès.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Copier après la connexion

Alors, comment ça se passe ? Découvrons-le aujourd'hui

Tout d'abord, créez un nouveau projet maven rick-spring-boot, et créez deux sous-projets, spring-boot et user. Le projet spring-boot consiste à simuler l'écriture manuscrite d'un simple springboot. . L'utilisateur est utilisé pour tester le spring-boot manuscrit.

Quel est le principe sous-jacent de SpringBoot ?

projet utilisateur-test projet

Le projet utilisateur contient pom.xml, UserController et UserService

<dependencies>
    <dependency>
      <groupId>com.rick.spring.boot</groupId>
      <artifactId>spring-boot</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>
Copier après la connexion
rrree# 🎜 🎜# et la classe de démarrage RickApplication du projet utilisateur, et RickSpringApplication.run() est une classe de démarrage qui doit être écrite à la main et l'annotation @RickSpringBootApplication, qui doivent toutes deux être implémentées dans le projet spring-boot.

@RestController
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/user")
    public String getUser() {
        return userService.getUser();
    }
}
@Service
public class UserService {
    public String getUser() {
        return "rick";
    }
}
Copier après la connexion

Springboot project

Regardons d'abord ce que la méthode RickSpringApplication.run(RickApplication.class) doit faire :

(1) Créer un conteneur Spring et enregistrez la classe entrante dans le conteneur Spring

(2) Démarrez un service Web, tel que Tomcat, pour traiter la demande et distribuez la demande au Servlet pour traitement via DispatchServlet.

import com.rick.spring.boot.RickSpringApplication;
import com.rick.spring.boot.RickSpringBootApplication;
@RickSpringBootApplication
public class RickApplication {
    public static void main(String[] args) {
        RickSpringApplication.run(RickApplication.class);
    }
}
Copier après la connexion

RickApplication est modifié par l'annotation @RickSpringBootApplication. À partir du code suivant, nous pouvons voir que RickApplication est une classe de configuration. Après avoir été enregistrée dans le conteneur Spring, Spring analysera cette classe.

public class RickSpringApplication {
    public static void run(Class clz) {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.register(clz);
        context.refresh();
        start(context);
    }
    public static void start(WebApplicationContext applicationContext) {
        System.out.println("start tomcat");
        Tomcat tomcat = new Tomcat();
        Server server = tomcat.getServer();
        Service service = server.findService("Tomcat");
        Connector connector = new Connector();
        connector.setPort(8081);
        Engine engine = new StandardEngine();
        engine.setDefaultHost("localhost");
        Host host = new StandardHost();
        host.setName("localhost");
        String contextPath = "";
        Context context = new StandardContext();
        context.setPath(contextPath);
        context.addLifecycleListener(new Tomcat.FixContextListener());
        host.addChild(context);
        engine.addChild(host);
        service.setContainer(engine);
        service.addConnector(connector);
        tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/*", "dispatcher");
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
    }
}
Copier après la connexion

Démarrer la méthode principale du projet utilisateur RickApplication,

Quel est le principe sous-jacent de SpringBoot ?

Access UserController

#🎜 🎜 #

Quel est le principe sous-jacent de SpringBoot ?Maintenant, un simple projet spring-boot a été intégré.

Configuration automatique

Réaliser la commutation entre Tomcat et Jetty

Lors de l'utilisation de Springboot, si nous ne voulons pas utiliser Tomcat comme service de traitement des requêtes , mais jetty Ou d'autres services Web, il suffit généralement d'exclure les dépendances tomcat pertinentes, puis d'introduire les dépendances jetty. Il s'agit du mécanisme d'assemblage automatique de springboot. Voyons ensuite comment il est implémenté

Définissez une interface de serveur Web et deux classes d'implémentation (tomcat et jetty), et écrivez le code pour démarrer les services tomcat et jetty

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Configuration
@ComponentScan
public @interface RickSpringBootApplication {
}
Copier après la connexion
public interface WebServer {
    void start();
}
public class JettyServer implements WebServer{
    @Override
    public void start() {
        System.out.println("start jetty");
    }
}
Copier après la connexion

Définissez l'interface AutoConfiguration pour identifier les classes qui doivent être automatiquement assemblées. Définissez une autre classe WebServerAutoConfiguration, qui est représentée comme une classe de configuration de Spring. Enfin, nous devons importer cette classe et laisser Spring l'analyser. Ensuite, Spring analysera la méthode d'annotation @Bean pour charger le Bean. Notez que les deux méthodes suivantes définissent également l'annotation @RickConditionalOnClass pour déterminer si le bean doit être analysé. Si les conditions sont remplies, le bean sera analysé. Autrement dit, si la classe stockée dans Tomcat ou le serveur est appliquée, le bean sera analysé. de la méthode correspondante sera analysée,

public class TomcatServer implements WebServer, ApplicationContextAware {
    private WebApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = (WebApplicationContext) applicationContext;
    }
    @Override
    public void start() {
        System.out.println("start tomcat");
        ...
        tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));
        context.addServletMappingDecoded("/*", "dispatcher");
        try {
            tomcat.start();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
    }
}
Copier après la connexion
# 🎜🎜# Regardons l'annotation @RickConditionalOnClass : Lorsque spring analyse une méthode annotée avec @RickConditionalOnClass, spring sait qu'elle est modifiée par @Conditional, et exécutera la correspondance () méthode de RickOnClassConditional pendant l'analyse pour déterminer si les conditions de chargement du bean sont remplies. match() essaiera de charger le nom du chemin de classe transmis si le fichier jar correspondant est introduit dans l'application, il se chargera avec succès et retournera true. Sinon, il retournera false.

public interface AutoConfiguration {
}
@Configuration
public class WebServerAutoConfiguration implements AutoConfiguration {
    @Bean
    @RickConditionalOnClass("org.apache.catalina.startup.Tomcat")
    public TomcatServer tomcatServer() {
        return new TomcatServer();
    }
    @Bean
    @RickConditionalOnClass("org.eclipse.jetty.server.Server")
    public JettyServer jettyWebServer() {
        return new JettyServer();
    }
}
Copier après la connexion

Présentation de WebServerAutoConfiguration, le moyen le plus simple et le plus grossier est d'importer cette classe via @Import(WebServerAutoConfiguration.class). Mais il est impossible pour Spring Boot de faire cela. Il n'est certainement pas bon d'écrire des centaines de configurations automatiques dans le code. Spring utilise le mécanisme SPI pour créer les répertoires et fichiers suivants dans le répertoire des ressources le JDK ServiceLoader charge les classes dans les fichiers ci-dessus. Lors de l'importation de cette classe via l'annotation @Import(WebServerImportSelector.class), Spring exécutera selectImports() lors de l'analyse de la classe de configuration, important ainsi WebServerAutoConfiguration dans le conteneur Spring, et Spring analysera cette classe de configuration.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Conditional(RickOnClassConditional.class)
public @interface RickConditionalOnClass {
    String value();
}
public class RickOnClassConditional implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Map<String, Object> annotation = metadata.getAnnotationAttributes(RickConditionalOnClass.class.getName());
        try {
            context.getClassLoader().loadClass((String) annotation.get("value"));
        } catch (ClassNotFoundException e) {
            return false;
        }
        return true;
    }
}
Copier après la connexion

À ce stade, Springboot peut basculer entre les services Tomcat et Jetty uniquement en modifiant la dépendance Maven du projet utilisateur

public class WebServerImportSelector implements DeferredImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        ServiceLoader<AutoConfiguration> load = ServiceLoader.load(AutoConfiguration.class);
        List<String> list = new ArrayList<>();
        for (AutoConfiguration loader : load) {
            list.add(loader.getClass().getName());
        }
        return list.toArray(new String[list.size()]);
    }
}
Copier après la connexion
Redémarrer le projet utilisateur

#🎜🎜 #Quel est le principe sous-jacent de SpringBoot ?

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal