通过手写模拟SpringBoot源码了解其中的逻辑原理,自动配置,整合Tomcat,启动过程等。
目录
![](https://img-blog.csdnimg.cn/img_convert/787feae2f133ddcf5602b50dc1964e31.png)
启动类
@MySpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class);
}
}
MySpringBootApplication注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
@ComponentScan
@Import(AutoConfigurationImportSelector.class)
public @interface MySpringBootApplication {
}
SpringApplication类
public class SpringApplication {
public static void run(Class clazz){
AnnotationConfigWebApplicationContext applicationContext=new AnnotationConfigWebApplicationContext();
applicationContext.register(clazz);
applicationContext.refresh();
WebServer webServer = getWebServer(applicationContext);
webServer.start(applicationContext);
}
private static WebServer getWebServer(ApplicationContext applicationContext){
Map<String, WebServer> webServers = applicationContext.getBeansOfType(WebServer.class);
if(webServers.isEmpty()){
throw new NullPointerException();
}
if(webServers.size()>1){
throw new IllegalStateException();
}
return webServers.values().stream().findFirst().get();
}
}
WebServerAutoConfiguration类
@Configuration
public class WebServerAutoConfiguration implements AutoConfiguration{
@Bean
@ConditionalOnClass("org.apache.catalina.startup.Tomcat")
public TomcatWebServer tomcatWebServer(){
return new TomcatWebServer();
}
}
TomcatWebServer类
public class TomcatWebServer implements WebServer{
public void start(AnnotationConfigWebApplicationContext applicationContext) {
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);
//Springmvc
tomcat.addServlet(contextPath,"dispatcher",new DispatcherServlet(applicationContext));
context.addServletMappingDecoded("/*","dispatcher");
try {
tomcat.start();
} catch (LifecycleException e) {
e.printStackTrace();
}
}
}
MyCondition 类
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Map<String, Object> annotationAttributes = annotatedTypeMetadata.getAnnotationAttributes(ConditionalOnClass.class.getName());
String className= (String) annotationAttributes.get("value");
try {
Class<?> aClass = conditionContext.getClassLoader().loadClass(className);
return true;
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
}
}
}
ConditionalOnClass注解
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyCondition.class)
public @interface ConditionalOnClass {
String value();
}
AutoConfigurationImportSelector类
public class AutoConfigurationImportSelector implements DeferredImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//jdk SPI
ServiceLoader<AutoConfiguration> serviceLoader = ServiceLoader.load(AutoConfiguration.class);
List<String> list=new ArrayList<>();
for (AutoConfiguration autoConfiguration : serviceLoader) {
list.add(autoConfiguration.getClass().getName());
}
return list.toArray(new String[0]);
}
}
文件源码下载地址在我的文件资源:https://download.csdn.net/download/qq_43649937/87521102