侧边栏壁纸
  • 累计撰写 781 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论
标签搜索

源码

Dettan
2021-04-10 / 0 评论 / 0 点赞 / 106 阅读 / 21,999 字
温馨提示:
本文最后更新于 2022-04-30,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。
用Xpath操纵xml

org.apache.ibatis.binding.MapperProxy
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  try {
    if (Object.class.equals(method.getDeclaringClass())) {
      return method.invoke(this, args);
    } else if (isDefaultMethod(method)) {
      return invokeDefaultMethod(proxy, method, args);
    }
  } catch (Throwable t) {
    throw ExceptionUtil.unwrapThrowable(t);
  }
  final MapperMethod mapperMethod = cachedMapperMethod(method);
  return mapperMethod.execute(sqlSession, args);
}
动态代理
java.lang.reflect.Proxy#newProxyInstance 这个方法是动态代理的方法,java提供的. 调用接口的时候就会代理一下了.

org.apache.ibatis.binding.MapperProxyFactory#newInstance(org.apache.ibatis.binding.MapperProxy<T>)
newInstance:47, MapperProxyFactory (org.apache.ibatis.binding)
newInstance:52, MapperProxyFactory (org.apache.ibatis.binding)
getMapper:50, MapperRegistry (org.apache.ibatis.binding)
getMapper:745, Configuration (org.apache.ibatis.session)
getMapper:318, SqlSessionTemplate (org.mybatis.spring)
getObject:95, MapperFactoryBean (org.mybatis.spring.mapper)
doGetObjectFromFactoryBean:168, FactoryBeanRegistrySupport (org.springframework.beans.factory.support)
getObjectFromFactoryBean:103, FactoryBeanRegistrySupport (org.springframework.beans.factory.support)
getObjectForBeanInstance:1601, AbstractBeanFactory (org.springframework.beans.factory.support)
doGetBean:254, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
findAutowireCandidates:1199, DefaultListableBeanFactory (org.springframework.beans.factory.support)
doResolveDependency:1123, DefaultListableBeanFactory (org.springframework.beans.factory.support)
resolveDependency:1021, DefaultListableBeanFactory (org.springframework.beans.factory.support)
inject:545, AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement (org.springframework.beans.factory.annotation)
inject:88, InjectionMetadata (org.springframework.beans.factory.annotation)
postProcessPropertyValues:331, AutowiredAnnotationBeanPostProcessor (org.springframework.beans.factory.annotation)
populateBean:1219, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:551, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:482, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:778, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:843, AbstractApplicationContext (org.springframework.context.support)
refresh:541, AbstractApplicationContext (org.springframework.context.support)
configureAndRefreshWebApplicationContext:666, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:632, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:680, FrameworkServlet (org.springframework.web.servlet)
initWebApplicationContext:551, FrameworkServlet (org.springframework.web.servlet)
initServletBean:492, FrameworkServlet (org.springframework.web.servlet)
init:136, HttpServletBean (org.springframework.web.servlet)
init:158, GenericServlet (javax.servlet)
initServlet:1134, StandardWrapper (org.apache.catalina.core)
loadServlet:1089, StandardWrapper (org.apache.catalina.core)
allocate:761, StandardWrapper (org.apache.catalina.core)
invoke:135, StandardWrapperValve (org.apache.catalina.core)
invoke:96, StandardContextValve (org.apache.catalina.core)
invoke:526, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:139, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:678, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:74, StandardEngineValve (org.apache.catalina.core)
service:343, CoyoteAdapter (org.apache.catalina.connector)
service:408, Http11Processor (org.apache.coyote.http11)
process:66, AbstractProcessorLight (org.apache.coyote)
process:861, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1579, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)

sqlsession 动态代理

org.mybatis.spring.SqlSessionTemplate#SqlSessionTemplate(org.apache.ibatis.session.SqlSessionFactory, org.apache.ibatis.session.ExecutorType, org.springframework.dao.support.PersistenceExceptionTranslator)

xml解析, 构建sqlsessionFactiory.
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	<property name="configLocation" value="classpath:mybatis.xml" />
	<property name="dataSource" ref="dataSource" />
</bean>

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.learn.dao" />
</bean>



C:/Users/liu/.ideaLibSources/mybatis-spring-1.3.1-sources.jar!/org/mybatis/spring/SqlSessionFactoryBean.java:546
org.mybatis.spring.SqlSessionFactoryBean

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {

//这个类继承了FactoryBean接口就是一个实例工厂了, spring就会调用这个方法创建这个类.
@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}

return this.sqlSessionFactory;
}

@Override
public void afterPropertiesSet() throws Exception {
notNull(dataSource, "Property 'dataSource' is required");
notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
"Property 'configuration' and 'configLocation' can not specified with together");

this.sqlSessionFactory = buildSqlSessionFactory();
}

protected SqlSessionFactory buildSqlSessionFactory() throws IOException {

Configuration configuration;

XMLConfigBuilder xmlConfigBuilder = null;
if (this.configuration != null) {
configuration = this.configuration;
if (configuration.getVariables() == null) {
configuration.setVariables(this.configurationProperties);
} else if (this.configurationProperties != null) {
configuration.getVariables().putAll(this.configurationProperties);
}
} else if (this.configLocation != null) {
xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
configuration = xmlConfigBuilder.getConfiguration();
} else {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Property configuration or 'configLocation' not specified, using default MyBatis Configuration");
}
configuration = new Configuration();
configuration.setVariables(this.configurationProperties);
}

if (this.objectFactory != null) {
configuration.setObjectFactory(this.objectFactory);
}

if (this.objectWrapperFactory != null) {
configuration.setObjectWrapperFactory(this.objectWrapperFactory);
}

if (this.vfs != null) {
configuration.setVfsImpl(this.vfs);
}

if (hasLength(this.typeAliasesPackage)) {
String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
for (String packageToScan : typeAliasPackageArray) {
configuration.getTypeAliasRegistry().registerAliases(packageToScan,
typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Scanned package: '" + packageToScan + "' for aliases");
}
}
}

if (!isEmpty(this.typeAliases)) {
for (Class<?> typeAlias : this.typeAliases) {
configuration.getTypeAliasRegistry().registerAlias(typeAlias);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Registered type alias: '" + typeAlias + "'");
}
}
}

if (!isEmpty(this.plugins)) {
for (Interceptor plugin : this.plugins) {
configuration.addInterceptor(plugin);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Registered plugin: '" + plugin + "'");
}
}
}

if (hasLength(this.typeHandlersPackage)) {
String[] typeHandlersPackageArray = tokenizeToStringArray(this.typeHandlersPackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
for (String packageToScan : typeHandlersPackageArray) {
configuration.getTypeHandlerRegistry().register(packageToScan);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Scanned package: '" + packageToScan + "' for type handlers");
}
}
}

if (!isEmpty(this.typeHandlers)) {
for (TypeHandler<?> typeHandler : this.typeHandlers) {
configuration.getTypeHandlerRegistry().register(typeHandler);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Registered type handler: '" + typeHandler + "'");
}
}
}

if (this.databaseIdProvider != null) {//fix #64 set databaseId before parse mapper xmls
try {
configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));
} catch (SQLException e) {
throw new NestedIOException("Failed getting a databaseId", e);
}
}

if (this.cache != null) {
configuration.addCache(this.cache);
}

//处理 mybatis.xml  里的&lt;configuration&gt;标签里的东西.

if (xmlConfigBuilder != null) {
try {
xmlConfigBuilder.parse();

  if (LOGGER.isDebugEnabled()) {
    LOGGER.debug(&quot;Parsed configuration file: '&quot; + this.configLocation + &quot;'&quot;);
  }
} catch (Exception ex) {
  throw new NestedIOException(&quot;Failed to parse config resource: &quot; + this.configLocation, ex);
} finally {
  ErrorContext.instance().reset();
}

}

if (this.transactionFactory == null) {
this.transactionFactory = new SpringManagedTransactionFactory();
}

configuration.setEnvironment(new Environment(this.environment, this.transactionFactory, this.dataSource));

if (!isEmpty(this.mapperLocations)) {
for (Resource mapperLocation : this.mapperLocations) {
if (mapperLocation == null) {
continue;
}

  try {
    XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
        configuration, mapperLocation.toString(), configuration.getSqlFragments());
    xmlMapperBuilder.parse();
  } catch (Exception e) {
    throw new NestedIOException(&quot;Failed to parse mapping resource: '&quot; + mapperLocation + &quot;'&quot;, e);
  } finally {
    ErrorContext.instance().reset();
  }

  if (LOGGER.isDebugEnabled()) {
    LOGGER.debug(&quot;Parsed mapper file: '&quot; + mapperLocation + &quot;'&quot;);
  }
}

} else {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Property 'mapperLocations' was not specified or no matching resources found");
}
}

return this.sqlSessionFactoryBuilder.build(configuration);
}




参数
<configuration>
<typeAliases>
&lt;/typeAliases&gt;

<mappers>
<mapper resource="com/hn/dao/AdminMapper.xml"/>
<mapper resource="com/hn/dao/AppraiseMapper.xml"/>
<mapper resource="com/hn/dao/FoodMapper.xml"/>
<mapper resource="com/hn/dao/OrdersMapper.xml"/>
<mapper resource="com/hn/dao/FoodOrderMapper.xml"/>
<mapper resource="com/hn/dao/UserMapper.xml"/>
<mapper resource="com/hn/dao/NoticeMapper.xml"/>
</mappers>
</configuration>

private void parseConfiguration(XNode root) {
try {
//issue #117 read properties first
propertiesElement(root.evalNode("properties"));
Properties settings = settingsAsProperties(root.evalNode("settings"));
loadCustomVfs(settings);
typeAliasesElement(root.evalNode("typeAliases"));
pluginElement(root.evalNode("plugins"));
objectFactoryElement(root.evalNode("objectFactory"));
objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
reflectorFactoryElement(root.evalNode("reflectorFactory"));
settingsElement(settings);
// read it after objectFactory and objectWrapperFactory issue #631
environmentsElement(root.evalNode("environments"));
databaseIdProviderElement(root.evalNode("databaseIdProvider"));
typeHandlerElement(root.evalNode("typeHandlers"));
mapperElement(root.evalNode("mappers"));
} catch (Exception e) {
throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);
}
}




参数
<mappers>
<mapper resource="com/hn/dao/AdminMapper.xml"/>
<mapper resource="com/hn/dao/AppraiseMapper.xml"/>
<mapper resource="com/hn/dao/FoodMapper.xml"/>
<mapper resource="com/hn/dao/OrdersMapper.xml"/>
<mapper resource="com/hn/dao/FoodOrderMapper.xml"/>
<mapper resource="com/hn/dao/UserMapper.xml"/>
<mapper resource="com/hn/dao/NoticeMapper.xml"/>
</mappers>

private void mapperElement(XNode parent) throws Exception {
if (parent != null) {
for (XNode child : parent.getChildren()) {
if ("package".equals(child.getName())) {
String mapperPackage = child.getStringAttribute("name");
configuration.addMappers(mapperPackage);
} else {
String resource = child.getStringAttribute("resource");
String url = child.getStringAttribute("url");
String mapperClass = child.getStringAttribute("class");
if (resource != null && url == null && mapperClass == null) {
ErrorContext.instance().resource(resource);
InputStream inputStream = Resources.getResourceAsStream(resource);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
mapperParser.parse();
} else if (resource == null && url != null && mapperClass == null) {
ErrorContext.instance().resource(url);
InputStream inputStream = Resources.getUrlAsStream(url);
XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, url, configuration.getSqlFragments());
//下下下下下下下下下下下下下下
mapperParser.parse();
} else if (resource == null && url == null && mapperClass != null) {
Class<?> mapperInterface = Resources.classForName(mapperClass);
configuration.addMapper(mapperInterface);
} else {
throw new BuilderException("A mapper element may only specify a url, resource or class, but not more than one.");
}
}
}
}
}




public void parse() {
    if (!configuration.isResourceLoaded(resource)) {
			//下下下下    解析xml文件
      configurationElement(parser.evalNode("/mapper"));
      configuration.addLoadedResource(resource);
      bindMapperForNamespace();
    }
parsePendingResultMaps();
parsePendingCacheRefs();
parsePendingStatements();

}




//解析mapper 文件 .
private void configurationElement(XNode context) {
    try {
      String namespace = context.getStringAttribute("namespace");
      if (namespace == null || namespace.equals("")) {
        throw new BuilderException("Mapper's namespace cannot be empty");
      }
      builderAssistant.setCurrentNamespace(namespace);
      cacheRefElement(context.evalNode("cache-ref"));
      cacheElement(context.evalNode("cache"));
      parameterMapElement(context.evalNodes("/mapper/parameterMap"));
			//获取文件里的所有 resultMap节点. 
      resultMapElements(context.evalNodes("/mapper/resultMap"));
      sqlElement(context.evalNodes("/mapper/sql"));
      buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
    } catch (Exception e) {
      throw new BuilderException("Error parsing Mapper XML. Cause: " + e, e);
    }
  }
解析xml里的resultMap
resultMapElement:285, XMLMapperBuilder (org.apache.ibatis.builder.xml)
resultMapElement:252, XMLMapperBuilder (org.apache.ibatis.builder.xml)
resultMapElements:244, XMLMapperBuilder (org.apache.ibatis.builder.xml)
configurationElement:116, XMLMapperBuilder (org.apache.ibatis.builder.xml)
parse:92, XMLMapperBuilder (org.apache.ibatis.builder.xml)
mapperElement:373, XMLConfigBuilder (org.apache.ibatis.builder.xml)
parseConfiguration:119, XMLConfigBuilder (org.apache.ibatis.builder.xml)
parse:99, XMLConfigBuilder (org.apache.ibatis.builder.xml)
buildSqlSessionFactory:494, SqlSessionFactoryBean (org.mybatis.spring)
afterPropertiesSet:380, SqlSessionFactoryBean (org.mybatis.spring)
invokeInitMethods:1642, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1579, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:553, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:482, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
resolveReference:351, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
resolveValueIfNecessary:108, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
applyPropertyValues:1486, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
populateBean:1231, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:551, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:482, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:759, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:843, AbstractApplicationContext (org.springframework.context.support)
refresh:541, AbstractApplicationContext (org.springframework.context.support)
configureAndRefreshWebApplicationContext:666, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:632, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:680, FrameworkServlet (org.springframework.web.servlet)
initWebApplicationContext:551, FrameworkServlet (org.springframework.web.servlet)
initServletBean:492, FrameworkServlet (org.springframework.web.servlet)
init:136, HttpServletBean (org.springframework.web.servlet)
init:158, GenericServlet (javax.servlet)
initServlet:1134, StandardWrapper (org.apache.catalina.core)
loadServlet:1089, StandardWrapper (org.apache.catalina.core)
allocate:761, StandardWrapper (org.apache.catalina.core)
invoke:135, StandardWrapperValve (org.apache.catalina.core)
invoke:96, StandardContextValve (org.apache.catalina.core)
invoke:526, AuthenticatorBase (org.apache.catalina.authenticator)
invoke:139, StandardHostValve (org.apache.catalina.core)
invoke:92, ErrorReportValve (org.apache.catalina.valves)
invoke:678, AbstractAccessLogValve (org.apache.catalina.valves)
invoke:74, StandardEngineValve (org.apache.catalina.core)
service:343, CoyoteAdapter (org.apache.catalina.connector)
service:408, Http11Processor (org.apache.coyote.http11)
process:66, AbstractProcessorLight (org.apache.coyote)
process:861, AbstractProtocol$ConnectionHandler (org.apache.coyote)
doRun:1579, NioEndpoint$SocketProcessor (org.apache.tomcat.util.net)
run:49, SocketProcessorBase (org.apache.tomcat.util.net)
runWorker:1149, ThreadPoolExecutor (java.util.concurrent)
run:624, ThreadPoolExecutor$Worker (java.util.concurrent)
run:61, TaskThread$WrappingRunnable (org.apache.tomcat.util.threads)
run:748, Thread (java.lang)

解析xml
configurationElement:118, XMLMapperBuilder (org.apache.ibatis.builder.xml)
parse:92, XMLMapperBuilder (org.apache.ibatis.builder.xml)
mapperElement:373, XMLConfigBuilder (org.apache.ibatis.builder.xml)
parseConfiguration:119, XMLConfigBuilder (org.apache.ibatis.builder.xml)
parse:99, XMLConfigBuilder (org.apache.ibatis.builder.xml)
buildSqlSessionFactory:494, SqlSessionFactoryBean (org.mybatis.spring)
afterPropertiesSet:380, SqlSessionFactoryBean (org.mybatis.spring)
invokeInitMethods:1642, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1579, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:553, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:482, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
resolveReference:351, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
resolveValueIfNecessary:108, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
applyPropertyValues:1486, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
populateBean:1231, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:551, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:482, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:759, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:843, AbstractApplicationContext (org.springframework.context.support)
refresh:541, AbstractApplicationContext (org.springframework.context.support)
configureAndRefreshWebApplicationContext:666, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:632, FrameworkServlet (org.springframework.web.servlet)
createWebApplicationContext:680, FrameworkServlet (org.springframework.web.servlet)
initWebApplicationContext:551, FrameworkServlet (org.springframework.web.servlet)
initServletBean:492, FrameworkServlet (org.springframework.web.servlet)
init:136, HttpServletBean (org.springframework.web.servlet)
init:158, GenericServlet (javax.servlet)
initServlet:1134, StandardWrapper (org.apache.catalina.core)
loadServlet:1089, StandardWrapper (org.apache.catalina.core)
0

评论区