spring tomcat启动 请求处理
onRefresh();
protected void onRefresh() {
try {
createEmbeddedServletContainer();
}
}
private void createEmbeddedServletContainer() {
EmbeddedServletContainer localContainer = this.embeddedServletContainer; //null
ServletContext localServletContext = getServletContext(); //null
if (localContainer == null && localServletContext == null) {
EmbeddedServletContainerFactory containerFactory = getEmbeddedServletContainerFactory(); //返回org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
this.embeddedServletContainer = containerFactory
.getEmbeddedServletContainer(getSelfInitializer()); //this = AnnotationConfigEmbeddedWebApplicationContext,返回
}
initPropertySources();
}
protected EmbeddedServletContainerFactory getEmbeddedServletContainerFactory() {
String[] beanNames = getBeanFactory()
.getBeanNamesForType(EmbeddedServletContainerFactory.class); //[tomcatEmbeddedServletContainerFactory]
return getBeanFactory().getBean(beanNames[],EmbeddedServletContainerFactory.class);
}
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);//tomcatEmbeddedServletContainerFactory,interface org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
}
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
try {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
} Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
} protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
}
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); //AnnotationAwareAspectJAutoProxyCreator判断要不要生成代理,
}
}
return null;
}
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args); //org.springframework.beans.BeanWrapperImpl: wrapping object [org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory@7a7cc52c]
Object exposedObject = bean;
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
return exposedObject;
}
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
Object wrappedBean = bean;
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
return wrappedBean;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
TomcatEmbeddedServletContainerFactory 类:
原来是通过server.xml解析的,这里是代码写死的。
public EmbeddedServletContainer getEmbeddedServletContainer(
ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();//org.apache.catalina.startup.Tomcat@620c8641
File baseDir = (this.baseDirectory != null ? this.baseDirectory
: createTempDir("tomcat"));//C:\Users\ADMINI~1\AppData\Local\Temp\tomcat.5396461944750847035.8086
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatEmbeddedServletContainer(tomcat);
}
public Connector(String protocol) {
setProtocol(protocol);
ProtocolHandler p = null;
try {
Class<?> clazz = Class.forName("org.apache.coyote.http11.Http11NioProtocol");
p = (ProtocolHandler) clazz.getConstructor().newInstance();
} finally {
this.protocolHandler = p;
}
}
public Server getServer() {
if (server != null) {
return server;
}
System.setProperty("catalina.useNaming", "false");
server = new StandardServer();
initBaseDir();
server.setPort( -1 );
Service service = new StandardService();
service.setName("Tomcat");
server.addService(service);
return server;
}
public Host getHost() {
Engine engine = getEngine();
if (engine.findChildren().length > 0) {
return (Host) engine.findChildren()[0];
}
Host host = new StandardHost();
host.setName(hostname);
getEngine().addChild(host);
return host;
}
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) {
return new TomcatEmbeddedServletContainer(tomcat, getPort() >= 0);
}
public TomcatEmbeddedServletContainer(Tomcat tomcat, boolean autoStart) {
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
initialize();
}
private void initialize() throws EmbeddedServletContainerException {
synchronized (this.monitor) {
try {
addInstanceIdToEngineName();
try {
final Context context = findContext();
this.tomcat.start();
}
}
}
public void start() throws LifecycleException {
getServer();
getConnector();
server.start();
}
public final synchronized void start() throws LifecycleException {
if (state.equals(LifecycleState.NEW)) {
init();
} else if (state.equals(LifecycleState.FAILED)) {
stop();
} else if (!state.equals(LifecycleState.INITIALIZED) &&
!state.equals(LifecycleState.STOPPED)) {
invalidTransition(Lifecycle.BEFORE_START_EVENT);
}
try {
setStateInternal(LifecycleState.STARTING_PREP, null, false);
startInternal();
if (state.equals(LifecycleState.FAILED)) {
stop();
} else if (!state.equals(LifecycleState.STARTING)) {
invalidTransition(Lifecycle.AFTER_START_EVENT);
} else {
setStateInternal(LifecycleState.STARTED, null, false);
}
}
}
public final synchronized void init() throws LifecycleException {
try {
initInternal();
}
}
protected void initInternal() throws LifecycleException {
for (int i = 0; i < services.length; i++) {
services[i].init();
}
}
public final synchronized void init() throws LifecycleException {
try {
initInternal();
}
}
protected void initInternal() throws LifecycleException {
if (engine != null) {
engine.init();
}
for (Executor executor : findExecutors()) {
if (executor instanceof JmxEnabled) {
((JmxEnabled) executor).setDomain(getDomain());
}
executor.init();
}
mapperListener.init();
synchronized (connectorsLock) {
for (Connector connector : connectors) {
try {
connector.init(); //里面会adapter = new CoyoteAdapter(this);,
}
}
}
}
解析requestMappingHandlerMapping是时候,
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) {
Object result = existingBean;//requestMappingHandlerMapping
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessBeforeInitialization(result, beanName);//beanProcessor = ApplicationContextAwareProcessor,
}
return result;
}
ApplicationContextAwareProcessor类:
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
else {
invokeAwareInterfaces(bean);
}
return bean;
}
protected void initInterceptors() {
if (!this.interceptors.isEmpty()) {
for (int i = 0; i < this.interceptors.size(); i++) {
Object interceptor = this.interceptors.get(i); //[WebRequestHandlerInterceptorAdapter, ConversionServiceExposingInterceptor, ResourceUrlProviderExposingInterceptor]
this.adaptedInterceptors.add(adaptInterceptor(interceptor));
}
}
}
initializeBean方法里面的invokeInitMethods(beanName, wrappedBean, mbd); 把url跟controller的映射注册到requestMappingHandlerMapping进去了
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) {
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
requestMappingHandlerMapping类:
public void afterPropertiesSet() {
super.afterPropertiesSet();
}
protected void initHandlerMethods() {
String[] beanNames = getApplicationContext().getBeanNamesForType(Object.class)); //所有的bean
for (String beanName : beanNames) {
if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {
Class<?> beanType = null;
try {
beanType = getApplicationContext().getType(beanName);
}
if (beanType != null && isHandler(beanType)) {
detectHandlerMethods(beanName); //beanName = accountController
}
}
}
handlerMethodsInitialized(getHandlerMethods());
}
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
protected void detectHandlerMethods(final Object handler) {
Class<?> handlerType = (handler instanceof String ?
getApplicationContext().getType((String) handler) : handler.getClass()); //class com.hcxy.car.controller.AccountController
final Class<?> userType = ClassUtils.getUserClass(handlerType); //class com.hcxy.car.controller.AccountController
Map<Method, T> methods = MethodIntrospector.selectMethods(userType,
new MethodIntrospector.MetadataLookup<T>() {
@Override
public T inspect(Method method) {
try {
return getMappingForMethod(method, userType);
}
}
});//{public Map AccountController.addAccount(java.util.Map) n={[/ota/account/add],methods=[POST]}, public Map AccountController.all1( )={[/ota/account/all],methods=[GET]}} for (Map.Entry<Method, T> entry : methods.entrySet()) {
Method invocableMethod = AopUtils.selectInvocableMethod(entry.getKey(), userType);
T mapping = entry.getValue();
registerHandlerMethod(handler, invocableMethod, mapping);
}
}
请求进来。从tomcat走到DispatcherServlet。
DispatcherServlet类: protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);//DefaultRequestToViewNameTranslator加到DispatcherServlet
initViewResolvers(context);//DefaultRequestToViewNameTranslator加到DispatcherServlet
initFlashMapManager(context);//DefaultRequestToViewNameTranslator加到DispatcherServlet
}
private void initHandlerMappings(ApplicationContext context) {
this.handlerMappings = null; //this = DispatcherServlet
if (this.detectAllHandlerMappings) {
Map<String, HandlerMapping> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false); //从容器找到所有的HandlerMapping,{requestMappingHandlerMapping=RequestMappingHandlerMapping@5ad6f98e, viewControllerHandlerMapping=WebMvcConfigurationSupport$EmptyHandlerMapping@786ff0ea, beanNameHandlerMapping=BeanNameUrlHandlerMapping@15186ce0, resourceHandlerMapping=SimpleUrlHandlerMapping@54bb1194, defaultServletHandlerMapping=WebMvcConfigurationSupport$EmptyHandlerMapping@1109730f, faviconHandlerMapping=SimpleUrlHandlerMapping@25109608, welcomePageHandlerMapping=WebMvcAutoConfiguration$WelcomePageHandlerMapping@38dbeb39}
if (!matchingBeans.isEmpty()) {
this.handlerMappings = new ArrayList<HandlerMapping>(matchingBeans.values()); //7个,
AnnotationAwareOrderComparator.sort(this.handlerMappings);
}
}
}
private void initHandlerAdapters(ApplicationContext context) {
this.handlerAdapters = null; //this = DispatcherServlet
if (this.detectAllHandlerAdapters) {
Map<String, HandlerAdapter> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false); //从容器中找{requestMappingHandlerAdapter=RequestMappingHandlerAdapter@45297e7, httpRequestHandlerAdapter=HttpRequestHandlerAdapter@5423a17, simpleControllerHandlerAdapter=SimpleControllerHandlerAdapter@42ff9a77}
if (!matchingBeans.isEmpty()) {
this.handlerAdapters = new ArrayList<HandlerAdapter>(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerAdapters);
}
}
}
private void initHandlerExceptionResolvers(ApplicationContext context) {
this.handlerExceptionResolvers = null; //this = DispatcherServlet
if (this.detectAllHandlerExceptionResolvers) {
Map<String, HandlerExceptionResolver> matchingBeans = BeanFactoryUtils
.beansOfTypeIncludingAncestors(context, HandlerExceptionResolver.class, true, false); //{errorAttributes=DefaultErrorAttributes@30cafd13, handlerExceptionResolver=HandlerExceptionResolverComposite@60f662bd}
if (!matchingBeans.isEmpty()) {
this.handlerExceptionResolvers = new ArrayList<HandlerExceptionResolver>(matchingBeans.values());
AnnotationAwareOrderComparator.sort(this.handlerExceptionResolvers);
}
}
private void initViewResolvers(ApplicationContext context) {
this.viewResolvers = null;//this = DispatcherServlet
if (this.detectAllViewResolvers) {
// Find all ViewResolvers in the ApplicationContext, including ancestor contexts.
Map<String, ViewResolver> matchingBeans =
BeanFactoryUtils.beansOfTypeIncludingAncestors(context, ViewResolver.class, true, false);
if (!matchingBeans.isEmpty()) {
this.viewResolvers = new ArrayList<ViewResolver>(matchingBeans.values());
//[org.springframework.web.servlet.view.BeanNameViewResolver@29090809, org.springframework.web.servlet.view.ViewResolverComposite@22aee519, org.springframework.web.servlet.view.InternalResourceViewResolver@7ba06506, org.springframework.web.servlet.view.ContentNegotiatingViewResolver@3e2c4d4b, org.thymeleaf.spring4.view.ThymeleafViewResolver@780129bc]
AnnotationAwareOrderComparator.sort(this.viewResolvers);
}
}
private void initFlashMapManager(ApplicationContext context) {
try {//this = DispatcherServlet
this.flashMapManager = context.getBean(FLASH_MAP_MANAGER_BEAN_NAME, FlashMapManager.class); //SessionFlashMapManager
}
请求进来,然后进到doService方法。
protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
try {
doDispatch(request, response);
}
}
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerExecutionChain mappedHandler = null; //拦截器链
try {
try {
processedRequest = checkMultipart(request); //上床文件,
multipartRequestParsed = (processedRequest != request);
mappedHandler = getHandler(processedRequest); //public java.util.Map com.hcxy.car.controller.AccountController.all1()
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // ha = RequestMappingHandlerAdapter
if (!mappedHandler.applyPreHandle(processedRequest, response)) { //前置拦截器
return;
}
//反射调用controller的方法。
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); applyDefaultViewName(processedRequest, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv); //后置拦截器
}
}
}
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
for (HandlerMapping hm : this.handlerMappings) {//[SimpleUrlHandlerMapping@7afbf2a0, RequestMappingHandlerMapping@349f0ca4, BeanNameUrlHandlerMapping@52ca0ad4, SimpleUrlHandlerMapping@2565a7d0, WebMvcConfigurationSupport$EmptyHandlerMapping@47f2c722, WebMvcConfigurationSupport$EmptyHandlerMapping@4fd7b79, WebMvcAutoConfiguration$WelcomePageHandlerMapping@7e050be1],只有RequestMappingHandlerMapping有url和controller的对应关系。
HandlerExecutionChain handler = hm.getHandler(request); //hm= RequestMappingHandlerMapping
if (handler != null) {
return handler;//public java.util.Map com.hcxy.car.controller.AccountController.all1()
}
}
return null;
}
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
for (HandlerAdapter ha : this.handlerAdapters) { //[RequestMappingHandlerAdapter@6e2eead5, HttpRequestHandlerAdapter@113eed88, SimpleControllerHandlerAdapter@5f0677f3]
if (ha.supports(handler)) {
return ha;//RequestMappingHandlerAdapter
}
}
}
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HandlerInterceptor[] interceptors = getInterceptors();//拦截器
if (!ObjectUtils.isEmpty(interceptors)) {
for (int i = 0; i < interceptors.length; i++) {
HandlerInterceptor interceptor = interceptors[i];
if (!interceptor.preHandle(request, response, this.handler)) {
}
this.interceptorIndex = i;
}
}
return true;
}
反射调用controller的方法。
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); //ha = RequestMappingHandlerAdapter
protected ModelAndView handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
else {
mav = invokeHandlerMethod(request, response, handlerMethod);
}
return mav;
}
protected <T> void writeWithMessageConverters(T value, MethodParameter returnType,
ServletServerHttpRequest inputMessage, ServletServerHttpResponse outputMessage) {
if (selectedMediaType != null) {
selectedMediaType = selectedMediaType.removeQualityValue();
for (HttpMessageConverter<?> messageConverter : this.messageConverters) {
if (messageConverter instanceof GenericHttpMessageConverter) {
if (((GenericHttpMessageConverter) messageConverter).canWrite(
declaredType, valueType, selectedMediaType)) {
outputValue = (T) getAdvice().beforeBodyWrite(outputValue, returnType, selectedMediaType,
(Class<? extends HttpMessageConverter<?>>) messageConverter.getClass(),
inputMessage, outputMessage); //{@11105} accounts -> {@11106} 12345,返回的Map。
if (outputValue != null) {
addContentDispositionHeader(inputMessage, outputMessage);
((GenericHttpMessageConverter) messageConverter).write(
outputValue, declaredType, selectedMediaType, outputMessage);
}
return;
}
}
}
}
}
objectWriter.writeValue(generator, value); //写出去数据给流浪器,从response写出去。
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); //视图响应 if (mv != null && !mv.wasCleared()) {//
render(mv, request, response); //渲染
if (errorView) {
WebUtils.clearErrorRequestAttributes(request);
}
}
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { View view;
if (mv.isReference()) {
view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);
}
}
else {
view = mv.getView();
} try {
if (mv.getStatus() != null) {
response.setStatus(mv.getStatus().value());
}
view.render(mv.getModelInternal(), request, response);
}
}
protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
HttpServletRequest request) throws Exception { for (ViewResolver viewResolver : this.viewResolvers) { //viewResolvers是视图解析器
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}
public View resolveViewName(String viewName, Locale locale) throws Exception {
if (!isCache()) {
return createView(viewName, locale);
}
spring tomcat启动 请求处理的更多相关文章
- tomcat启动(Ⅶ)请求处理--Processor.process(SocketWrapper<S> socketWrapper)
tomcat启动(六)Catalina分析-StandardServer.start() 上一篇分析到:Http11NioProcessor.process(SocketWrapper<S> ...
- hibernate+spring+tomcat启动报错Not supported by BasicDataSource
最近使用hibernate+spring+jsp的小项目制作过程中出现一些错误,例如: java.lang.UnsupportedOperationException: Not supported b ...
- Spring + Tomcat 启动报错java.lang.ClassNotFoundException: org.apache.commons.pool.impl.GenericObjectPool
错误如下: -- ::,-[TS] INFO http-- org.springframework.beans.factory.support.DefaultListableBeanFactory - ...
- [spring+tomcat]启动时报错:NoSuchMethodError: javax.servlet.http.HttpServletResponse.getStatus()I
一般来讲问题的原因为tomcat版本较低, 建议升级到tomcat7x 以上版本
- Spring Tomcat启动过程
入口,配置再web.xml中, 初始化applicationContext 创建webApplicationContext,这里可加载web.xml文件中定义了contextClass 获取conte ...
- Spring Boot启动过程(四):Spring Boot内嵌Tomcat启动
之前在Spring Boot启动过程(二)提到过createEmbeddedServletContainer创建了内嵌的Servlet容器,我用的是默认的Tomcat. private void cr ...
- Spring Boot 添加jersey-mvc-freemarker依赖后内置tomcat启动不了解决方案
我在我的Spring Boot 项目的pom.xml中添加了jersey-mvc-freemarker依赖后,内置tomcat启动不了. 报错信息如下: org.springframework.con ...
- spring boot tomcat 打本地包成war,通过Tomcat启动时出现问题: ZipException: error in opening zip file
一个第三方公司提供spring boot 项目,直接启动是ok的, 但是打包成war,通过Tomcat启动,就出现 ZipException: error in opening zip file: 2 ...
- Spring Boot:内置tomcat启动和外部tomcat部署总结
springboot的web项目的启动主要分为: 一.使用内置tomcat启动 启动方式: 1.IDEA中main函数启动 2.mvn springboot-run 命令 3.java -jar XX ...
随机推荐
- linux服务器上配置进行kaggle比赛的深度学习tensorflow keras环境详细教程
本文首发于个人博客https://kezunlin.me/post/6b505d27/,欢迎阅读最新内容! full guide tutorial to install and configure d ...
- WPF属性绑定实现双向变化
WPF依赖项属性可以实现属性的绑定,成功绑定之后只要修改后台绑定的属性,即可UI同步自动更新绑定的值,无需手动刷新界面:同样,前台的值变化后,通过获取绑定的属性值也可获取UI变化后的值,实现双向变化的 ...
- webpack基本使用
webpack安装时的坑 高版本的webpack除了全局安装webpack外,还需安装webpack-cli,在本地使用时也一样需要这样,不然会出错 webpack使用是的坑 在原始启动webpack ...
- 深入理解JVM,7种垃圾收集器
本人免费整理了Java高级资料,一共30G,需要自己领取.传送门:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q 如果说收集算法是内存回收的方法论, ...
- 网上售卖几百一月的微信机器,Python几十行代码就能搞定
前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 故事胶片 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...
- swoole 内存泄露的问题有没有好的办法解决
在传统的web开发模式中,我们知道,每一次php请求,都要经过php文件从磁盘上读取.初始化.词法解析.语法解析.编译等过程,而且还要与nginx或者apache通信,如果再涉及数据库的交互,还要再 ...
- Maven设置本地仓和阿里云远程仓
在maven项目导入jar包坐标时需要连接maven官方仓库下载,但是下载速度感人,所以来修改一下设置. 设置成为本地仓和连接阿里云的远程仓库. (本地仓如果没有这个jar) 找出相应配置文件:例如我 ...
- 易优CMS:关于assign你知道多少
[基础用法] 名称:assign 功能:模板文件中定义变量,可在其他标签里使用该变量 语法: {eyou:assign name='typeid' value='5' /} 文件: 无 参数: nam ...
- 合格的施工图是如何绘制的?必须要get这四点,大多数人都不知道
对于工程设计师来说加班通宵赶图改图是常有的事情,如何绘制一套合格的施工图?这是很多工程设计师都会问的问题. 绘制一套合格的施工图,你需要注意以下四点: 一.明确施工图的作用和目的 1. 工程设计的细化 ...
- centos 安装gitlab
1.开始安装依赖软件:yum -y install policycoreutils openssh-server openssh-clients postfix 2.设置postfix开机自启动,po ...