springboot使用的是嵌入式的servlet容器。
依赖关系图:
---
编写一个嵌入式的servlet的定制器。此时我们写的是一个定制器,注意不是一个@Bean。
配置的properties也是一个嵌入式的servlet控制器。
总结:
---
几句重要的话:
-----------------------------------46------------------------------------------------------
原来是:
servlet的三大组件。
案例:
代码:https://www.cnblogs.com/LiuOOP/p/11208830.html
https://blog.csdn.net/u012410733/article/details/51746178
https://blog.csdn.net/jacksonary/article/details/84572701
第一步:写一个servlet
第二步:如何起作用?
package com.atguigu.springboot.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("contextInitialized...web应用启动");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("contextDestroyed...当前web项目销毁");
}
}
package com.atguigu.springboot.filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("MyFilter process...");
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
package com.atguigu.springboot.component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 登陆检查,
*/
public class LoginHandlerInterceptor implements HandlerInterceptor {
//目标方法执行之前
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("loginUser");
if(user == null){
//未登陆,返回登陆页面
request.setAttribute("msg","没有权限请先登陆");
request.getRequestDispatcher("/index.html").forward(request,response);
return false;
}else{
//已登陆,放行请求
return true;
}
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
看下DispatherServlet是如何注册的,也是一个组件。
总结:https://www.jianshu.com/p/b973476ccfd6
代码:
源码:
package com.atguigu.springboot.config;
import com.atguigu.springboot.component.LoginHandlerInterceptor;
import com.atguigu.springboot.component.MyLocaleResolver;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
//@EnableWebMvc 不要接管SpringMVC
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /atguigu 请求来到 success
registry.addViewController("/atguigu").setViewName("success");
}
//所有的WebMvcConfigurerAdapter组件都会一起起作用
@Bean //将组件注册在容器
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/main.html").setViewName("dashboard");
}
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//super.addInterceptors(registry);
//静态资源; *.css , *.js
// SpringBoot已经做好了静态资源映射
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/user/login");
}
};
return adapter;
}
@Bean
public LocaleResolver localeResolver(){
return new MyLocaleResolver();
}
}
package com.atguigu.springboot.config;
import com.atguigu.springboot.filter.MyFilter;
import com.atguigu.springboot.listener.MyListener;
import com.atguigu.springboot.servlet.MyServlet;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
@Configuration
public class MyServerConfig {
//配置嵌入式的Servlet容器
@Bean
public EmbeddedServletContainerCustomizer embeddedServletContainerCustomizer(){
return new EmbeddedServletContainerCustomizer() {
//定制嵌入式的Servlet容器相关的规则
@Override
public void customize(ConfigurableEmbeddedServletContainer container) {
container.setPort(8083);
}
};
}
//注册三大组件
@Bean
public ServletRegistrationBean myServlet(){
ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
registrationBean.setLoadOnStartup(1);
return registrationBean;
}
@Bean
public FilterRegistrationBean myFilter(){
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new MyFilter());
registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
return registrationBean;
}
@Bean
public ServletListenerRegistrationBean myListener(){
ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(new MyListener());
return registrationBean;
}
}
----------------------------------47--------------------------------------------------------
自动配置原理:
第一步:
第二步:
第三步:
第四步:我们看下嵌入式的servlet容器工厂,获取嵌入式的servlet容器。
第五步:工厂创建嵌入式的servlet容器,进入工厂tomcat的容器
第六步:点进去最后那个方法
启动tomcat容器
第七步:我们的修改是如何生效的呢?
第八步:
导入了嵌入式容器servlet的后置处理器。
---
进入这个后置处理器
首先判断下的。
进入下面的方法:
拿到容器所有的定制器,遍历每个定制器的方法。
另外一个,也是一个嵌入式的容器定制器:
---------------------------------------------49----------------------------------------------
servlet容器工厂的启动原理:
第一步:嵌入式的servlet容器的自动配置类,放了一个容器工厂。
第二步:容器工厂什么时候创建嵌入式容器的。
启动:
在主方法开始:
第三步:创建ioc容器
判断是不是web的,不是就创建一般的容器。
第四步:
第五步:
第六步:这个刷新方法就是spring注解版本的刷新方法。
创建嵌入式的servlet容器。
和之前联系上了。
总结:
这个截图第二个应该是create。
4.onRefresh(),被重写了;
5.
6.
这一步惊动了后置处理器。
7.
8.
先启动嵌入式的servlet容器,再将ioc的其他的的对象创建出来。
---------------------------------------------50----------------------------------------------