SpringBoot——嵌入式 Servlet容器

这篇具有很好参考价值的文章主要介绍了SpringBoot——嵌入式 Servlet容器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、如何定制和修改Servlet容器的相关配置

前言: SpringBootWeb环境下,默认使用的是Tomact作为嵌入式的Servlet容器;

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

【1】修改和server相关的配置(ServerProperties实现了EmbeddedServletContainerCustomizer)例如:修改端口号

#通用的Servlet容器设置:修改端口号
server:
  port: 8081
  tomcat:  #设置Tomact的相关属性,例如编码格式
    uri-encoding: utf-8

☞ 我们也可以进入port所属的对象中,发现其他可修改的参数等等,如下:

@ConfigurationProperties(
    prefix = "server",
    ignoreUnknownFields = true
)
public class ServerProperties implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
    private Integer port;
    private InetAddress address;
    private String contextPath;
    private String displayName = "application";
    ......

【2】编写一个EmbeddedServletContainerCustomizer:嵌入式的 Servlet容器的定制器,来修改 Servlet容器的配置。其实1中的 ServerProperties也是实现了 EmbeddedServletContainerCustomizer。xxxCustomizer 帮组我们进行定制配置。

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Bean
    public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
        return new EmbeddedServletContainerCustomizer() {
            @Override
            public void customize(ConfigurableEmbeddedServletContainer container) {
                container.setPort(8082);
            }
        };
    }

二、注册Servlet三大组件【Servlet、Filter、Listener】

由于SpringBoot默认是以 jar包的方式启动嵌入的Servlet容器来启动SpringBootweb应用,没有web.xml文件。注册三大组件的方式如下:

【1】通过 ServletRegistrationBean注册自定义的Servlet

//首先创建一个Servlet
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Hello MyServlet");
        super.doPost(req, resp);
    }
}

//将创建的Servlet通过配置类注入到容器中,两个是不同的类。
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Bean
    public ServletRegistrationBean myServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(), "/myServlet");
        return registrationBean;
    }

【2】通过 FilterRegistrationBean 注册拦截器 Filter。

//自定义一个filter实现servlet.Filter接口
public class myFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.printf("myFilter");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

//通过配置类注入自定义的Filter
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    @Bean
    public FilterRegistrationBean myFilter(){
        FilterRegistrationBean registrationBean = new FilterRegistrationBean();
        registrationBean.setFilter(new myFilter());
        registrationBean.setUrlPatterns(Arrays.asList("/hello","/myFilter"));
        return registrationBean;
    }3】通过`ServletListenerRegistrationBean`注册自定义的`Listener`。
```java
//创建自定义的Listener监听
public class myListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.printf("服务启动");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.printf("服务销毁");
    }
}

//通过配置类注入自定义的listener
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {

    public ServletListenerRegistrationBean myListener(){
        ServletListenerRegistrationBean<MyListener> servletListenerRegistrationBean = new ServletListenerRegistrationBean<>(new MyListener());
        return servletListenerRegistrationBean;
    }

三、使用其他 Servlet容器:Jetty(长连接引用)、Undertow(不支持JSP)

【1】我们在定制嵌入式的Servlet容器时,会传入ConfigurableEmbeddedServletContainer类,我们通过Ctrl+T查看此可配置嵌入式类容器中可以配置TomcatJettyUndertow

//ConfigurableEmbeddedServletContainer 
@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
    return new EmbeddedServletContainerCustomizer() {
        @Override
        public void customize(ConfigurableEmbeddedServletContainer container) {
            container.setPort(8082);
        }
    };
}

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

【2】默认使用Tomcat,因为starter-web引入的是Tomcatstarter。我们排除Tomcat的依赖,引入Jetty的依赖即可。

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
	<exclusions>
		<exclusion>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<groupId>org.springframework.boot</groupId>
		</exclusion>
	</exclusions>
</dependency>

<dependency>
	<artifactId>spring-boot-starter-Jetty</artifactId>
	<groupId>org.springframework.boot</groupId>
</dependency>

四、嵌入式 Servlet容器自动配置原理

【1】EmbeddedServletContainerAutoConfiguration类主要用来自动配置嵌入式的Servlet容器。

@AutoConfigureOrder(-2147483648)
@Configuration
@ConditionalOnWebApplication
 //导入BeanPostProcessorsRegistrar:后置处理器:在bean初始化前后,执行(刚创建完对象,还没属性赋值)初始化工作.
 //给容器中导入一些组件,导入了embeddedServletContainerCustomizerBeanPostProcessor
@Import({EmbeddedServletContainerAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class EmbeddedServletContainerAutoConfiguration {
    @Configuration
    @ConditionalOnClass({Servlet.class, Tomcat.class})//判断当前Servlet中是否引入的Tomcat依赖
    @ConditionalOnMissingBean(
        value = {EmbeddedServletContainerFactory.class},
        search = SearchStrategy.CURRENT
    )//判断当前容器中,没有用户自定义的EmbeddedServletContainerFactory嵌入式的Servlet容器工厂,
    //作用:创建嵌入式的servlet容器。
    public static class EmbeddedTomcat {
        public EmbeddedTomcat() {
        }

        @Bean
        public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
            return new TomcatEmbeddedServletContainerFactory();
        }
    }

    @Configuration
    @ConditionalOnClass({Servlet.class, Undertow.class, SslClientAuthMode.class})
    @ConditionalOnMissingBean(
        value = {EmbeddedServletContainerFactory.class},
        search = SearchStrategy.CURRENT
    )
    public static class EmbeddedUndertow {
        public EmbeddedUndertow() {
        }

        @Bean
        public UndertowEmbeddedServletContainerFactory undertowEmbeddedServletContainerFactory() {
            return new UndertowEmbeddedServletContainerFactory();
        }
    }

    @Configuration
    @ConditionalOnClass({Servlet.class, Server.class, Loader.class, WebAppContext.class})
    @ConditionalOnMissingBean(
        value = {EmbeddedServletContainerFactory.class},
        search = SearchStrategy.CURRENT
    )
    public static class EmbeddedJetty {
        public EmbeddedJetty() {
        }

        @Bean
        public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
            return new JettyEmbeddedServletContainerFactory();
        }
    }
}

【2】嵌入式的容器工厂:EmbeddedServletContainerFactory,用来创建嵌入式的Servlet容器。

public interface EmbeddedServletContainerFactory {
     //获取嵌入式的Servlet容器
     EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... var1); 
}

☛ SpringBoot 再带了三种嵌入式的容器工厂,如下:

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

【3】EmbeddedServletContainer:嵌入式的容器,SpringBoot 为我们提供了三种不同的嵌入式容器,与工厂相互对应,如下:

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

【4】我们进入工厂类 TomcatEmbeddedServletContainerFactory发现,其实也是创建一个 Tomcat并配置其基本属性。

public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
	//创建Tomcat
	Tomcat tomcat = new Tomcat();

	//配置Tomcat的基本环境
	File baseDir = this.baseDirectory != null?this.baseDirectory:this.createTempDir("tomcat");
	tomcat.setBaseDir(baseDir.getAbsolutePath());
	Connector connector = new Connector(this.protocol);
	tomcat.getService().addConnector(connector);
	this.customizeConnector(connector);
	tomcat.setConnector(connector);
	tomcat.getHost().setAutoDeploy(false);
	this.configureEngine(tomcat.getEngine());
	Iterator var5 = this.additionalTomcatConnectors.iterator();

	while(var5.hasNext()) {
		Connector additionalConnector = (Connector)var5.next();
		tomcat.getService().addConnector(additionalConnector);
	}

	this.prepareContext(tomcat.getHost(), initializers);
	//将配置好的Tomcat传入,并启动Tomcat,Tomcat.start()
	return this.getTomcatEmbeddedServletContainer(tomcat);
}

【5】用户自定义的Servlet容器配置类和SpringBoot默认的ServerProperties配置类,都实现了EmbeddedServletContainerCustomizer接口。到底是怎么实现的哪?其实是SpringBoot自动配置类中引入了后置处理器,如下:

//与用户自定义的Servlet容器实现的接口名很类似,有一定的命名规则。
embeddedServletContainerCustomizerBeanPostProcessor

☛ 进入后置处理器类中,重点看如下代码:

//初始化之前执行
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
	//如果当前初始化的是当前ConfigurableEmbeddedServletContainer类型的组件
	if(bean instanceof ConfigurableEmbeddedServletContainer) {
		this.postProcessBeforeInitialization((ConfigurableEmbeddedServletContainer)bean);
	}

	return bean;
}

//上面的postProcessBeforeInitialization方法:
private void postProcessBeforeInitialization(ConfigurableEmbeddedServletContainer bean) {
	Iterator var2 = this.getCustomizers().iterator();

	while(var2.hasNext()) {
		//获取所有的定制器,调用每一个定制器的customize方法来给servlet属性赋值。
		EmbeddedServletContainerCustomizer customizer = (EmbeddedServletContainerCustomizer)var2.next();
		customizer.customize(bean);
	}

private Collection<EmbeddedServletContainerCustomizer> getCustomizers() {
	if(this.customizers == null) {
		//this.beanFactory.xx表示从容器中获取XXCustomizer自定义类型的组件
		this.customizers = new ArrayList(this.beanFactory.getBeansOfType(EmbeddedServletContainerCustomizer.class, false, false).values());
		Collections.sort(this.customizers, AnnotationAwareOrderComparator.INSTANCE);
		this.customizers = Collections.unmodifiableList(this.customizers);
	}

	return this.customizers;
}

整理下步骤:
【1】SpringBoot根据pom.xml中导入的依赖,给容器中添加其对应的嵌入式的服务容器工厂类,例如默认的Tomcat工厂:EmbeddedServletContainerFactory【TomcatEmbeddedServletContainerFactory】
【2】给容器中某个组件要创建对象就会触发后置处理器EmbeddedServletContainerCustomizerBeanPostProcessor,只要是嵌入式的Servlet容器工厂,后置处理器就会工作(默认的ServerProperties也是实现了此类接口的,所以肯定存在相关配置类)
【3】后置处理器从容器中获取所有的EmbeddedServletContainerCustomizer,调用定制器的定制方法。

五、嵌入式Servlet容器启动原理

根据上述的流程,我们要研究Servlet容器的启动原理。其实就是研究什么时候创建嵌入式的容器工厂和何时获取嵌入式的容器并启动Tomcat。获取嵌入式的Servlet容器工厂的过程(在new TomcatEmbeddedServletContainerFactory()时打一个断电,查看过程):
【1】SpringBoot 应用启动运行 run() 方法。
【2】this.refreshContext(context) 方法:用来初始化 IOC容器,既创建 IOC容器对象并初始化IOC容器中的每一个组件。

protected ConfigurableApplicationContext createApplicationContext() {
	Class<?> contextClass = this.applicationContextClass;
	if(contextClass == null) {
		try {
			//判断是不是web环境,是Web环境引入AnnotationConfigEmbeddedWebApplicationContext,否则引入AnnotationConfigApplicationContext
			contextClass = Class.forName(this.webEnvironment
			?"org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext"
			:"org.springframework.context.annotation.AnnotationConfigApplicationContext");
		} catch (ClassNotFoundException var3) {
			throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
		}
	}

	return (ConfigurableApplicationContext)BeanUtils.instantiate(contextClass);
}

【3】this.refresh(context):刷新刚才创建好的IOC容器。
【4】this.onRefresh()webIoC容器重写了onRefresh()方法。

protected void onRefresh() {
	super.onRefresh();

	try {
		//重点是创建了嵌入式的Servlet容器
		this.createEmbeddedServletContainer();
	} catch (Throwable var2) {
		throw new ApplicationContextException("Unable to start embedded container", var2);
	}
}

【5】this.createEmbeddedServletContainer()webIOC容器会创建嵌入式的Servlet容器。

private void createEmbeddedServletContainer() {
	EmbeddedServletContainer localContainer = this.embeddedServletContainer;
	ServletContext localServletContext = this.getServletContext();
	if(localContainer == null && localServletContext == null) {
		// 1、获取嵌入式的Servlet嵌入式的工厂
		EmbeddedServletContainerFactory containerFactory = this.getEmbeddedServletContainerFactory();
		this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(
				new ServletContextInitializer[]{this.getSelfInitializer()});
	} 
}

【6】获取嵌入式工厂后,便可从容器中获取EmbeddedServletContainerFactory的组件tomcatEmbeddedServletContainerFactory来创建Tomcat对象,后置处理器就会触发获取所有的定制器来确定Servlet容器的相关配置。
【7】通过嵌入式工厂获取嵌入式容器,如下:

this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(
                new ServletContextInitializer[]{this.getSelfInitializer()});

● 嵌入式的Servlet容器创建并启动对象:

public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
    //创建对象
    Tomcat tomcat = new Tomcat();

    //启动对象
    this.tomcat.start();

● 先启动嵌入式的Servlet容器,再将IOC容器中剩下没有创建的对象进行初始化,如下:

    this.onRefresh();
    //启动完嵌入式容器后,后续还有其他对象的初始化工作
    this.registerListeners();
    this.finishBeanFactoryInitialization(beanFactory);
    this.finishRefresh();
} catch (BeansException var9) {

六、使用外置的Servlet容器

嵌入式Servlet容器的缺点: 默认不支持JSP、优化和定制比较复杂。外置Servlet容器:安装外部的Tomcat,步骤如下:

1)、必须创建一个war项目,需要手动创建目录(利用Idea快速创建)如下:

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

2)、将嵌入式的Tomcat指定为provide(Idea创建完后,会自动帮我们完成,但我们需要了解)

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-tomcat</artifactId>
	<scope>provided</scope>
</dependency>

3)、需要编写一个SpringBootServletInitializer的子类,并调用configure方法:

public class ServletInitializer extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		return application.sources(SpringBootWebApplication.class);
	}
}

4)、配置本地的Tomcat,并启动Tomcat即可。(此项目运行run()方法是不能启动项目的):需要设置名称和本地Tomcat的路径即可使用外部Servlet。

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

七、外置服务器的使用原理

☞ jar包:执行SpringBoot主类的main方法,启动并初始化IOC容器且创建嵌入式的Servlet容器。
☞ war包:启动服务器后调用SpringBootServletInitializer中的configure()方法,加载我们的SpringBoot应用并启动。

Servlet3.0规则:
 1)、服务器启动后,会创建当前web应用中包含的每个jar内的ServletContainerInitializer实例。
 2)、ServletContainerInitializer的实现放在jar包的META-INF/services文件夹下(javax.servlet.ServletContainerInitializer:内容就是ServletContainerInitializer的全类名)
 3)、可以使用@handlesTypes注解,在应用启动时加载我们需要的类。

流程:
 1)、启动Tomcat后,获取servlet.ServletContainerInitializer文件如下:其中的内容同下:

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

#文件中的内容
org.springframework.web.SpringServletContainerInitializer

 2)、进入SpringServletContainerInitializer发现此类将@HandlesTypes({WebApplicationInitializer.class})标注的所有这个类型的类都传入到onStartup方法中的Set<Class<?>>,并为这些类创建实例。

@HandlesTypes({WebApplicationInitializer.class})
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    //onStartup方法,用来实例化感兴趣的对象
    public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException {
        if(webAppInitializerClasses != null) {
            var4 = webAppInitializerClasses.iterator();

            while(var4.hasNext()) {
                Class<?> waiClass = (Class)var4.next();
                if(!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
                    try {
                            //实例化
                       initializers.add((WebApplicationInitializer)waiClass.newInstance());
                    } catch (Throwable var7) {
                        throw new ServletException("Failed to instantiate WebApplicationInitializer class", var7);
                    }
                }
            }
        }

 3)、每一个WebApplicationInitializer都调用自己的onStartup()方法。

while(var4.hasNext()) {
	  WebApplicationInitializer initializer = (WebApplicationInitializer)var4.next();
	  //onStartup()方法
	  initializer.onStartup(servletContext);
 }

 4)、WebApplicationInitializer只是一个接口,其实现类主要有以下三个:SpringBootServletInitalizer正是SpringBoot给我们创建好的启动类,会被创建对象,并启动自身的onStartup()方法。

SpringBoot——嵌入式 Servlet容器,SpringBoot,spring boot,servlet,后端,服务器,java,spring,职场和发展

 5)、执行onStartup()方法时,会调用createRootApplicationContext()方法来创建容器

public void onStartup(ServletContext servletContext) throws ServletException {
        this.logger = LogFactory.getLog(this.getClass());
        //创建容器
        WebApplicationContext rootAppContext = this.createRootApplicationContext(servletContext);
        if(rootAppContext != null) {
            servletContext.addListener(new ContextLoaderListener(rootAppContext) {
                public void contextInitialized(ServletContextEvent event) {
                }
            });

    //容器的具体调用实现
    protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
        //创建Spring应用的构建器
        SpringApplicationBuilder builder = this.createSpringApplicationBuilder();
        //设置主类
        builder.main(this.getClass());
        //创建一些环境
        ApplicationContext parent = this.getExistingRootWebApplicationContext(servletContext);
        if(parent != null) {
            this.logger.info("Root context already created (using as parent).");
            servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, (Object)null);
            builder.initializers(new ApplicationContextInitializer[]{new ParentContextApplicationContextInitializer(parent)});
        }

        builder.initializers(new ApplicationContextInitializer[]{new ServletContextApplicationContextInitializer(servletContext)});
        builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class);

        //重要:子类中重写了此方法,子类出入了应用的主程序类
        builder = this.configure(builder);
        builder.listeners(new ApplicationListener[]{new SpringBootServletInitializer.WebEnvironmentPropertySourceInitializer(servletContext, null)});
        //使用build()创建一个Spring应用
        SpringApplication application = builder.build();
        if(application.getAllSources().isEmpty() && AnnotationUtils.findAnnotation(this.getClass(), Configuration.class) != null) {
            application.addPrimarySources(Collections.singleton(this.getClass()));
        }

        Assert.state(!application.getAllSources().isEmpty(), "No SpringApplication sources have been defined. Either override the configure method or add an @Configuration annotation");
        if(this.registerErrorPageFilter) {
            application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
        }
        //启动应用
        return this.run(application);
    }

 6)、执行应用的run()方法,来启动Spring应用并创建IOC容器。文章来源地址https://www.toymoban.com/news/detail-758302.html

public ConfigurableApplicationContext run(String... args) {
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	ConfigurableApplicationContext context = null;
	Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
	this.configureHeadlessProperty();
	SpringApplicationRunListeners listeners = this.getRunListeners(args);
	listeners.starting();

	Collection exceptionReporters;
	try {
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
		ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
		this.configureIgnoreBeanInfo(environment);
		Banner printedBanner = this.printBanner(environment);
		context = this.createApplicationContext();
		exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, new Object[]{context});
		this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);

		//刷新IOC容器
		this.refreshContext(context);
		this.afterRefresh(context, applicationArguments);
		stopWatch.stop();
		if(this.logStartupInfo) {
			(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
		}

		listeners.started(context);
		this.callRunners(context, applicationArguments);
	} catch (Throwable var10) {
		this.handleRunFailure(context, var10, exceptionReporters, listeners);
		throw new IllegalStateException(var10);
	}

	try {
		listeners.running(context);
		return context;
	} catch (Throwable var9) {
		this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
		throw new IllegalStateException(var9);
	}
}

到了这里,关于SpringBoot——嵌入式 Servlet容器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式系统>嵌入式硬件知识

    AI芯片的特点包括 :新型计算范式AI芯片的关键特征: 1、新型的计算范式 AI 计算既不脱离传统计算,也具有新的计算特质,如处理的内容往往是非结构化数据(视频、图片等)。处理的过程通常需要很大的计算量,基本的计算主要是线性代数运算,而控制流程则相对简单。

    2024年02月08日
    浏览(55)
  • 嵌入式操作系统(嵌入式学习)

    嵌入式操作系统是一种专门设计和优化用于嵌入式系统的操作系统。它是在资源受限的嵌入式设备上运行的操作系统,如微控制器、嵌入式处理器和系统芯片等。 嵌入式操作系统的主要目标是提供对硬件资源的有效管理和对应用程序的调度,以实现系统的可靠性、实时性和效

    2024年02月10日
    浏览(60)
  • 关于嵌入式开发的一些信息汇总:嵌入式C开发人员、嵌入式系统Linux

    这篇文章是关于嵌入式开发的一些基本信息,供想入行的人参考。有一些作者本人的想法,以及来自外网的大拿的文章翻译而来,原文链接在此Learning Linux for embedded systems,再次感谢,支持原创。 普通C开发人员和嵌入式C开发人员之间的 基本区别在于 ,因为嵌入式C程序被设

    2024年02月03日
    浏览(71)
  • 适合嵌入式开发的GUI(嵌入式学习)

    嵌入式开发中的GUI(图形用户界面)是指在嵌入式系统中实现图形化的用户界面,以便用户可以通过触摸屏、按钮、鼠标或其他输入设备与系统进行交互。 以下是一些常见的嵌入式GUI开发方法: 轻量级GUI库:一些轻量级的GUI库适用于嵌入式系统,例如uGFX、LittlevGL、Nanogui等。

    2024年02月09日
    浏览(69)
  • 嵌入式Linux:如何进行嵌入式Linux开发?

    目录 1、裸机开发 2、SDK开发 3、驱动开发 3.1、字符设备驱动 3.2、块设备驱动 3.3、网络设备驱动 4、应用开发 嵌入式Linux开发主要有四种方式:裸机开发、SDK开发、驱动开发和应用开发。 裸机开发通常指在没有操作系统支持的环境中直接在硬件上运行程序的开发。这种开发方

    2024年01月25日
    浏览(80)
  • 【嵌入式学习笔记】嵌入式入门2——中断(外部中断)

    打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断 作用1: 实时控制在确定时间内对相应事件作出响应 ——定时器中断 作用2: 故障处理检测到故障,需要第一时间处理 ——外部中断 作用3: 数据传输不确定数据何时会来 ——串口中断

    2024年02月08日
    浏览(74)
  • Spring Boot各版本与Java版本的对应兼容关系,与构建工具(Maven、Gradle)版本的对应兼容关系,对servlet 容器的支持

    by:垃圾程序员 当前文章具有时效性,在当前springboot的版本下做的整合。之后大家视情况可以直接到Spring的官网查看 Spring | Home Level up your Java code and explore what Spring can do for you. https://spring.io/ 下面是Spring Boot各个版本的支持时间 下面是Spring Boot 推荐使用的各个版面,并标注出

    2024年02月10日
    浏览(53)
  • 【计算机三级嵌入式】考试自学笔记(三)——嵌入式系统硬件组成、嵌入式处理芯片以及存储器介绍

    常考知识点: 嵌入式最小硬件组成 嵌入式处理芯片 嵌入式系统的存储器 I/O接口及常用I/O设备 ARM内核典型嵌入式处理芯片 嵌入式系统外部通信接口 嵌入式最小硬件系统的组成如下: 嵌入式硬件系统≠嵌入式最小硬件系统 电源电路 :为整个嵌入式系统提供能量 时钟电路 :

    2023年04月12日
    浏览(88)
  • 嵌入式开发:单片机嵌入式Linux学习路径

    SOC(System on a Chip)的本质区别在于架构和功能。低端SOC如基于Cortex-M架构的芯片,如STM32和NXP LPC1xxx系列,不具备MMU(Memory Management Unit),适用于轻量级实时操作系统如uCOS和FreeRTOS。高端SOC如基于Cortex-A架构的芯片,如三星、高通、飞卡、全志和瑞芯微等,具备MMU,支持虚拟内

    2024年02月15日
    浏览(57)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(87)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包