IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SpringBoot 自动配置原理 -> 正文阅读

[Java知识库]SpringBoot 自动配置原理


?

使用的springboot源码版本 2.3.12.RELEASE
?

@EnableAutoConfiguration

@EnableAutoConfiguration 是 @SpringBootApplication 包含的三大注解之一,用于启用自动装配

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	Class<?>[] exclude() default {};

	String[] excludeName() default {};

}

启用自动配置后,springboot会跟根据classpath包含的jar包、应用中定义的bean推测需要自动配置的bean。如果手动进行了配置,则不会再使用对应的自动配置。

可以用 exclude 或 excludeName 排除不使用的自动配置类,exclude 是以Class对象形式指定,excludeName 是以字符串形式指定类名。
?

@EnableAutoConfiguration 包含了2个注解

  • @AutoConfigurationPackage:指定自动配置要应用的包,即要对应用中的哪些包使用自动配置
  • @Import(AutoConfigurationImportSelector.class):导入 AutoConfigurationImportSelector 组件,这个类用于导入、筛选spring.factories中指定的自动配置类

?

spring.factories中AutoConfiguration相关配置

spring-boot-autoconfigure 的 spring.factories,相关内容如下

# 自动配置导入监听器
# 这个继承的是jdk的事件监听器 EventListener,不是spring的 ApplicationListener
org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
org.springframework.boot.autoconfigure.condition.ConditionEvaluationReportAutoConfigurationImportListener


# 自动配置类导入过滤器
org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition


# 自动配置类
# 注解是 @interface 类型,本质是一种特殊的接口,此处的 EnableAutoConfiguration 即 @EnableAutoConfiguration 注解
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

自动配置相关的有3项

  • AutoConfigurationImportListener:指定自动配置导入监听器。会在导入自动配置时对应的回调方法。
  • EnableAutoConfiguration:指定自动配置类。springboot提供了大量的自动配置类,涵盖了常用的组件、框架。
  • AutoConfigurationImportFilter:指定自动配置类的过滤器。

EnableAutoConfiguration 指定的是springboot提供的全部自动配置类,AutoConfigurationImportFilter 用于对自动配置类进行筛选、过滤,根据classpath、应用中定义的bean推断可能要使用的自动配置类,最后只导入可能要使用的自动配置类。

?

AutoConfigurationImportFilter的过滤机制

AutoConfigurationImportFilter 是如何对自动配置类进行筛选过滤的?是如何推断可能要使用的自动配置类的?这其实是一个问题。
?

先看 spring.factories 中指定的自动配置类,随便点开一个,基本都是:类上使用了 @Configuration 标注为bean,类中使用@Bean标注了bean,使用 @Conditional 系列注解校验这2个注解的是否满足条件。
?

再看 spring.factories 中指定的自动配置类过滤器

org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
org.springframework.boot.autoconfigure.condition.OnBeanCondition,\
org.springframework.boot.autoconfigure.condition.OnClassCondition,\
org.springframework.boot.autoconfigure.condition.OnWebApplicationCondition

都是 XxxCondition 类,检测自动配置类中定义的bean是否满足 @Conditional 系列注解指定的条件

  • OnBeanCondition:校验 @ConditionalOnBean、@ConditionalOnSingleCandidate
  • OnClassCondition:校验 @ConditionalOnClass、@ConditionalOnMissingClass
  • OnWebApplicationCondition:校验 @ConditionalOnWebApplication
    ?

显然,过滤机制是

通过 @Conditional 系列注解校验自动配置类中定义的bean是否满足条件,满足条件才作为bean放到容器,以提供对应的自动配置,否则不会放到容器中,不提供对应的自动配置。

所谓智能推测可能要使用的自动配置类,其实就是通过 @Conditional 系列注解根据web应用类型,classpath中有没有框架、组件的核心类,容器中有没有框架、组件的核心bean来判断应用可能使用了哪些框架、组件,给这些框架、组件提供对应的自动配置类。

?

BeanFactory加载bean定义时,自动配置提供的bean总是在自定义的bean之后加载,因为一些 @Conditional 注解要根据容器中的一些自定义bean来检查条件。
?

@Conditional 系列注解的介绍可以查看我的另一篇博文:

?

@AutoConfigurationPackage 自动配置要应用的包

/**
 * Registers packages with AutoConfigurationPackages. 
 * When no base packages or base package classes are specified, the package of the annotated class is registered.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class) //导入 AutoConfigurationPackages 组件
public @interface AutoConfigurationPackage {

	String[] basePackages() default {};

	Class<?>[] basePackageClasses() default {};

}

@AutoConfigurationPackage 用于指定自动配置要应用的包,即对应用中的哪些包、类提供|使用自动配置。

注释提到,没用 basePackages 属性指定要应用的包、类时,默认为此注解所标注的类所在的包。这个注释随着@SpringBootApplication被标注在引导类上,所以默认是对引导类所在的包应用自动配置。

@Import 导入的 AutoConfigurationPackages.Registrar 类会把要应用的 basePackages 作为bean注册到容器中。

?

AutoConfigurationImportSelector 自动配置导入选择器

@EnableAutoConfiguration 导入了一个组件

@Import(AutoConfigurationImportSelector.class)

AutoConfigurationImportSelector,顾名思义,用于导入 spring.factories 中指定的自动配置类时,对其进行筛选、过滤。

?

AutoConfigurationImportSelector 部分源码

/**
 * 从classpath的 spring.factories 文件中加载 EnableAutoConfiguration 所有要使用的实现类(自动配置类)
 * 
 * @return List<String>,所有自动配置类的类名列表
 */
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
	// getSpringFactoriesLoaderFactoryClass() 的值是 EnableAutoConfiguration.class
	List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
			getBeanClassLoader());
	Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
			+ "are using a custom packaging, make sure that file is correct.");
	return configurations;
}


/**
 * 对全部的自动配置类进行筛选、过滤,返回应用可能要使用的自动配置类
 * 
 * @return AutoConfigurationEntry,封装了可能要使用的以及要排除的自动配置类
 */
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
		return EMPTY_ENTRY;
	}
	AnnotationAttributes attributes = getAttributes(annotationMetadata);
	//获取 spring.factories 中指定的所有自动配置类
	List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
	//去掉重复的自动配置类
	configurations = removeDuplicates(configurations);
	//根据注解元数据获取 exclude、excludeName 属性的值
	Set<String> exclusions = getExclusions(annotationMetadata, attributes);
	//检查 exclude、excludeName 属性设置的值是否有效
	checkExcludedClasses(configurations, exclusions);
	//去掉 exclude、excludeName 排除的自动配置类
	configurations.removeAll(exclusions);
	//用 spring.factories 中指定的自动配置类过滤器对自动配置类进行筛选、过滤
	configurations = getConfigurationClassFilter().filter(configurations);
	//调用 spring.factories 中配置的自动配置导入监听器的回调方法
	//是直接调用监听器中的回调方法,不是以广播器发布事件的形式触发回调
	fireAutoConfigurationImportEvents(configurations, exclusions);
	//至此,configurations中的自动配置类都是可能要使用的。
	//封装可能要使用的以及要排除的自动配置类返回
	return new AutoConfigurationEntry(configurations, exclusions);
}

?

getConfigurationClassFilter().filter(configurations);使用过滤器校验的部分代码

//遍历自动配置类过滤器
for (AutoConfigurationImportFilter filter : this.filters) {
	//校验自动配置类中定义的所有bean是否满足当前过滤器的条件
	//关注这个match()
	boolean[] match = filter.match(candidates, this.autoConfigurationMetadata);
	for (int i = 0; i < match.length; i++) {
		if (!match[i]) {
			candidates[i] = null;
			skipped = true;
		}
	}
}

?

match()方法的实现中有一行

//记录 @Conditional 注解的匹配|校验结果
report.recordConditionEvaluation(autoConfigurationClasses[i], this, outcomes[i]);

自动配置类的匹配信息很多,IO操作很耗时,不会立刻打印,而是定义了一个监听器 ConditionEvaluationReportLoggingListener,监听ContextRefreshedEvent 事件,上下文刷新后发布上下文已刷新事件,触发监听器回调,打印自动配置类的匹配信息,匹配信息默认以debug级别进行打印。
?

debug模式下打印的匹配信息如下

2021-10-19 13:32:28.340  INFO 33444 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path '/mall'

#以下是监听器 ConditionEvaluationReportLoggingListener 打印的自动配置类匹配信息(debug级别)
2021-10-19 13:32:28.357 DEBUG 33444 --- [           main] ConditionEvaluationReportLoggingListener : 


============================
CONDITIONS EVALUATION REPORT
============================


Positive matches:
-----------------

   AopAutoConfiguration matched:
      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)

   AopAutoConfiguration.ClassProxyingConfiguration matched:
      - @ConditionalOnMissingClass did not find unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
      - @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
      - found 'session' scope (OnWebApplicationCondition)

	......

?

总结

springboot的自动配置是通过 @SpringBootApplication 中包含的 @EnableAutoConfiguration 注解实现的。

这个注解包含了 @AutoConfigurationPackage 注解,用于指定自动配置要应用的包,默认为引导类所在的包。

并用 @Import 导入了 AutoConfigurationImportSelector 类,这个类会
在启动的时候从classpath路径下的 META-INF/spring.factories 中获取 EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-20 12:21:41  更:2021-10-20 12:22:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 21:52:00-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码