美文网首页
手写springboot的核心流程

手写springboot的核心流程

作者: 天空_dst | 来源:发表于2022-10-26 00:42 被阅读0次

    spring容器以及Tomcat启动流程

    1. CasSpringApplication的run方法中启动spring容器
    public class CasSpringApplication { 
        public static void run(Class clazz) {
            // 启动sprinng容器
            AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
            context.register(clazz);
            context.refresh();
            // 启动服务
            start(context);
       }
    }
    
    1. 定义服务
      2.1 定义接口
    public interface WebServer {
        void start();
    }
    

    2.2 Tomcat实现类

    public class TomcatWebServer implements WebServer {
        @Override
        public void start() {
            System.out.println("tomcat 启动了");
        }
    }
    

    2.3 Jetty实现类

    public class JettyWebServer implements WebServer {
        @Override
        public void start() {
            System.out.println("jetty 启动了");
        }
    }
    

    2.3 获取实现类

     public static void start(AnnotationConfigWebApplicationContext applicationContext) {
        Map<String, WebServer> webserver = applicationContext.getBeansOfType(WebServer.class);
        if (webserver.size() > 1) {
            throw new RuntimeException("获取到多个服务");
        }
        webserver.values().stream().findFirst().get().start();
    }
    
    1. 动态选择服务
    • 如果项目中有Tomcat就启动Tomcat
    • 如果项目中有Jetty则启动Jetty
      3.1 条件注解
    @Target({ ElementType.TYPE, ElementType.METHOD })
    @Retention(RetentionPolicy.RUNTIME)
    @Conditional(CondationOnExitClass.class)
    public @interface CondationOnExit {
        String value() default "";
    }
    

    3.2 CondationOnExitClass实现类

    public class CondationOnExitClass implements Condition {
        @Override
        public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
            MultiValueMap<String, Object> map = metadata.getAllAnnotationAttributes(CondationOnExit.class.getName());
            String className = (String) map.getFirst("value");
            try {
                context.getClassLoader().loadClass(className);
                return true;
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                return false;
            }
        }
    }
    

    3.3spring容器中注入bean

    @Configuration
    public class WebServerBean {
        @Bean
        @CondationOnExit("org.apache.catalina.startup.Tomcat")
        public TomcatWebServer tomcatWebServer() {
            return new TomcatWebServer();
        }
    
        @Bean
        @CondationOnExit("org.eclipse.jetty.server.Server")
        public JettyWebServer jettyWebServer() {
            return new JettyWebServer();
        }
    }
    

    springboot的包扫描

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Configuration
    @ComponentScan
    public @interface CasSpringBoot {
    }
    

    springboot 自动装配

    • spring有一套自己实现的spi机制 在这里使用java自带的spi 暂时不做太复杂
    public class AutoImportSelect implements DeferredImportSelector {
        @Override
        public String[] selectImports(AnnotationMetadata importingClassMetadata) {
            // java spi
            ServiceLoader<AutoConfiguation> configuations = ServiceLoader.load(AutoConfiguation.class);
            List<String> list = new ArrayList<>();
            for (AutoConfiguation configuation : configuations) {
               list.add(configuation.getClass().getName());
            }
            return list.toArray(new String[0]);
        }
    }
    

    这个类无法被spring包扫描到 我们需要手动导入

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Configuration
    @ComponentScan
    @Import({AutoImportSelect.class}) // 导入自动装配类
    public @interface CasSpringBoot {
    }
    

    测试

    至此我们一个极简版springboot就实现完毕了

    @CasSpringBoot
    public class CasApplication {
        public static void main(String[] args) {
            CasSpringApplication.run(CasApplication.class);
        }
    }
    

    相关文章

      网友评论

          本文标题:手写springboot的核心流程

          本文链接:https://www.haomeiwen.com/subject/xmnozrtx.html