阅读 45

ZooKeeper分布式专题与Dubbo微服务入门

download:ZooKeeper分布式专题与Dubbo微服务入门

ZooKeeper是一种分布式协调服务,他用简单的架构和API,解决了在分布式环境中协调和管理服务的难题。本课程从零开始,带你系统学习ZooKeeper,并结合Dubbo,实践服务治理和分布式锁,帮你入门ZooKeeper+Dubbo的服务治理

适合人群及技术储备要求
具备一定项目经验,想了解分布式管理和微服务治理的同学,即可来学习!学完本课程,
不管是在你实际工作开发还是面试找工作,都能助你崭露头角!

技术储备要求:

  • 熟练使用Spring、SpringMVC、MyBatis

  • 具备Linux基础知识

  • 熟悉MySQL/Mariadb或者其他关系型数据库

  • contextConfigLocation classpath\*:application-context.xml
    <listener-class>org.springframework.web.context.ContextLoaderListener
    
    <servlet-name>dispatcher
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
    <init-param>
        <param-name>contextConfigLocation
        <param-value>classpath*:spring-mvc.xml
    
    <load-on-startup>1
    复制代码
    dispatcher /\*

能夠看到我們配置了ContextLoaderListener,他完成了ServletContextListener,在xml中配置了這個監聽器,啟動容器時,會自動執行完成的contextInitialized()辦法,

在ServletContextListener中的中心逻輯便是初始化WebApplicationContext實例並寄存至ServletContext中,這樣我們只需得到Servlet就能夠得到WebApplicationContext對象,並應用這個對象訪問spring容器管理的bean。

public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!");
}
servletContext.log("Initializing Spring root WebApplicationContext");
Log logger = LogFactory.getLog(ContextLoader.class);
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
long startTime = System.currentTimeMillis();
try {
// Store context in local instance variable, to guarantee that
// it is available on ServletContext shutdown.
// 創立得到WebApplicationContext,也就是ioc容器
// createWebApplicationContext最後返回值被強迫轉換爲ConfigurableWebApplicationContext類型
if (this.context == null) {
this.context = createWebApplicationContext(servletContext);
}
if (this.context instanceof ConfigurableWebApplicationContext) {
//強迫轉換爲ConfigurableWebApplicationContext
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
// cwac尚未被激活,目前還沒有停止配置文件加载
if (!cwac.isActive()) {
// The context has not yet been refreshed -> provide services such as
// setting the parent context, setting the application context id, etc
if (cwac.getParent() == null) {
// The context instance was injected without an explicit parent ->
// determine parent for root web application context, if any.
ApplicationContext parent = loadParentContext(servletContext);
cwac.setParent(parent);
}
//加载配置文件,也就是上面配置的applicationContext.xml文件
configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
//將ioc設置爲本人的父容器,這樣的話子容器能夠訪問父容器,但是父容器(ioc容器)不能訪問子容器(DispatcherServlet)
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext = this.context;
}
else if (ccl != null) {
currentContextPerThread.put(ccl, this.context);
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext initialized in " + elapsedTime + " ms");
}
return this.context;
}
catch (RuntimeException | Error ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
然後開端初始化DispatcherServlet,DispatcherServlet完成了Servlet接口,

public interface Servlet {
/**

  • 容器啟動時被調用(當load-on-startup爲負數或者不設置時,會在第一次被運用時才調用),只會調用一次
  • 它有一個參數ServletConfig,是容器傳進來的,表示的是這個Servlet的一些配置,比方DispatcherServlet配置的
    */
    public void init(ServletConfig config) throws ServletException;
    /**
  • 獲取Servlet的配置
    */
    public ServletConfig getServletConfig();
    /**
  • 最重要的一個辦法,是詳細處置懇求的中央
    */
    public void service(ServletRequest req, ServletResponse res)
    throws ServletException, IOException;
    /**
  • 獲取Servlet的一些信息,比方作者、版本、版權等,需求子類完成
    */
    public String getServletInfo();
    /**
  • 用於Servlet銷毀(主要指關閉容器)時释放一些資源,只會調用一次
    */
    public void destroy();
    }
    init辦法開端初始化容器

public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
}
// 獲取Servlet的初始化參數,對Bean屬性停止配置
try {
PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
initBeanWrapper(bw);
bw.setPropertyValues(pvs, true);
}
catch (BeansException ex) {
logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
throw ex;
}
// 調用子類的initServletBean辦法停止詳細的初始化工作
initServletBean();
if (logger.isDebugEnabled()) {
logger.debug("Servlet '" + getServletName() + "' configured successfully");
}
}
// initServletBean這個初始化工作位

文章分类
后端
文章标签