精华内容
参与话题
问答
  • Vue生命周期可以总共分为8个阶段

    万次阅读 2018-07-23 12:28:23
    Vue生命周期可以总共分为8个阶段: beforeCreate(创建前), created(创建后), beforeMount(载入前), mounted(载入后), beforeUpdate(更新前), updated(更新后), beforeDestroy(销毁前), destroyed(销毁...

    Vue生命周期可以总共分为8个阶段:

    beforeCreate(创建前),
    created(创建后),
    beforeMount(载入前),
    mounted(载入后),
    beforeUpdate(更新前),
    updated(更新后),
    beforeDestroy(销毁前),
    destroyed(销毁后)

    展开全文
  • 生命周期

    2020-08-04 19:33:36
    什么是生命周期? 通俗的讲任何事物都有它的一个生命周期比如说: 1、自然界的动植物生命周期:从初生到死亡。 2、产品的生命周期:从立项到淘汰。(一般指提市场寿命) 那vue的生命周期是什么? vue生命周期是指vue...

    什么是生命周期?

    通俗的讲任何事物都有它的一个生命周期比如说:
    1、自然界的动植物生命周期:从初生到死亡。
    2、产品的生命周期:从立项到淘汰。(一般指提市场寿命)

    那vue的生命周期是什么?

    vue生命周期是指vue实例对象从创建之初到销毁的过程,vue所有功能的实现都是围绕其生命周期进行的,在生命周期的不同阶段调用对应的钩子函数实现组件数据管理和DOM渲染两大重要功能。

    vue生命周期可以分为八个阶段,分别是:
    beforeCreate(创建前) 在数据观测和初始化事件还未开始

    created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来

    beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。

    mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。

    beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。

    updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
    beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。

    destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。

    创建前(beforecreate)
    在初始化之后,此时的数据和数据观察和事件机制都不由形成,所以不能操作

    生命周期表

    在这里插入图片描述

    展开全文
  • 使用vue框架,需要在合适的时机做合适的事情,了解了vue对象的生命周期和钩子函数,才能知道,哪些事情应该咋哪个函数里做。 一、vue的生命周期的理解 生命周期 用人举例说明: 生命周期就是一个人的一生,此处...

    官方图(官方的图大家总是理解不了):

            使用vue框架,需要在合适的时机做合适的事情,了解了vue对象的生命周期和钩子函数,才能知道,哪些事情应该咋哪个函数里做。

    一、vue的生命周期的理解

    1. 生命周期

    用人举例说明:

    生命周期就是一个人的一生,此处我需要说的没有人情一点(哈哈)。

    从人的出生,到成长,到工作,到死亡,就是人的一生,也叫一个人的生命周期。

         2. 对象的生命周期

    在程序开发中,是要使用对象的。那么,对象的生命周期就是:从对象的创建,到使用对象,到对象的消亡就是对象的生命周期。

    用人和对象进行类比(此处没有人性):

    程序中的对象

    人出生

    New对象

    人工作(ps:要人的目的就是为了工作,如果一个人不工作,不为国家做贡献,那就不是合格的人,活着没有意义)

    使用对象的方法和属性(ps:new的对象的目的就是为了用它,用对象主要就是使用对象的方法和属性)

    人死亡(ps:人没有用了,那就“去死吧”)

    对象使用完就该消亡了(过河拆桥,不用了,那就不要了。)

     

    3. Vue的生命周期

    Vue实例,vue组件实例就是vue对象,也是对象。所以,vue的生命周期和对象的生命周期是同样的道理

     

    二、vue生命周期经历的阶段

     

    生命周期是有不同的阶段的,就像人一样,有幼儿期,童年期,少年期,青年期,中年期,老年期。每个阶段应该做不同的事情,但是每个人做的事情又不尽相同。

    Vue对象的生命周期也分不同的阶段,不同的阶段也可以做不同的事情,但是不同的vue(组件)对象在不同的阶段做的事情也不尽相同,所以,每个vue组件的代码不相同。

    Vue生命周期经历哪些阶段:

    1. 总体来说:初始化、运行中、销毁
    2. 详细来说:开始创建、初始化数据、编译模板、挂载Dom、渲染更新渲染、销毁等一系列过程

     

    三、生命周期经历的阶段和钩子函数

     

    1. 实例化vue(组件)对象:new Vue()
    2. 初始化事件和生命周期 init events init cycle
    3. beforeCreate函数:

    在实例初始化之后,数据观测 (data observer) event/watcher 事件配置之前被调用。

    即此时vue(组件)对象被创建了,但是vue对象的属性还没有绑定,如data属性,computed属性还没有绑定,即没有值。

    此时还没有数据和真实DOM

    即:属性还没有赋值,也没有动态创建template属性对应的HTML元素(二阶段的createUI函数还没有执行)

         4. 挂载数据(属性赋值)

    包括 属性和computed的运算,

          5. Created函数:

    vue对象的属性有值了,但是DOM还没有生成,$el属性还不存在。

    此时有数据了,但是还没有真实的DOM

           即:datacomputed都执行了。属性已经赋值,但没有动态创建template属性对应的HTML元素,所以,此时如果更改数据不会触发updated函数

           如果:数据的初始值就来自于后端,可以发送ajax,或者fetch请求获取数据,但是,此时不会触发updated函数

        6. 检查

           1)检查是否有el属性
    检查vue配置,即new Vue{}里面的el项是否存在,有就继续检查template项。没有则等到手动绑定调用vm.$mount()

    完成了全局变量$el的绑定。

            2)检查是否有template属性

    检查配置中的template项,如果没有template进行填充被绑定区域,则被绑定区域的el对象的outerHTML(即整个#app DOM对象,包括<div id=”app” ></div>标签)都作为被填充对象替换掉填充区域

    即:如果vue对象中有 template属性,那么,template后面的HTML会替换$el对应的内容。如果有render属性,那么render就会替换template

    即:优先关系时: render  >  template > el

    beforeMount函数:

    模板编译(template)、数据挂载(把数据显示在模板里)之前执行的钩子函数

    此时 this.$el有值,但是数据还没有挂载到页面上。即此时页面中的{{}}里的变量还没有被数据替换

    8.模板编译:用vue对象的数据(属性)替换模板中的内容

    9. Mounted函数:

    模板编译完成,数据挂载完毕

    即:此时已经把数据挂载到了页面上,所以,页面上能够看到正确的数据了。

    一般来说,我们在此处发送异步请求(ajaxfetchaxios等),获取服务器上的数据,显示在DOM里。

    10. beforeUpdate函数:

    组件更新之前执行的函数,只有数据更新后,才能调用(触发)beforeUpdate,注意:此数据一定是在模板上出现的数据,否则,不会,也没有必要触发组件更新(因为数据不出现在模板里,就没有必要再次渲染)

    数据更新了,但是,vue(组件)对象对应的dom中的内部(innerHTML)没有变,所以叫作组件更新前

    11. updated函数:

    组件更新之后执行的函数

    vue(组件)对象对应的dom中的内部(innerHTML)改变了,所以,叫作组件更新之后

    12.  activated函数:keep-alive组件激活时调用

    13.  deactivated函数:keep-alive组件停用时调用

    14.  beforeDestroyvue(组件)对象销毁之前

    15.  destroyedvue组件销毁后

    四、测试代码

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>vue生命周期学习</title>
      </head>
    <body>
      <div id="app">
        <h1>{{message}}</h1>
        <h1>count:{{count}}</h1>
      </div>
      <input id="btn01" type="button" value="测试" />
    </body>
    <script type="text/javascript" src="js/vue.min.js" ></script>
    <script>
      var vm = new Vue({
        el: '#app',
        data: {
          message: 'Vue的生命周期',
          age:2
        },
        computed:{
        	count:function(){
        		return this.age+1;
        	}
        },
    //  template:"<p>vue对象中的template的内容</p>",
    //  render: function(createElement) {
    //      return createElement('h1', 'this is createElement')
    //  },
        beforeCreate: function() {
          console.group('------beforeCreate创建前状态------');
          console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined
          console.log("%c%s", "color:red","data   : " + this.$data); //undefined 
         console.log("%c%s", "color:red","count   : " + this.count); //undefined 
          console.log("%c%s", "color:red","message: " + this.message) 
        },
        created: function() {
          console.group('------created创建完毕状态------');
          console.log("%c%s", "color:red","el     : " + this.$el); //undefined
          console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化 
          console.log("%c%s", "color:red","count   : " + this.count); //undefined 
          console.log("%c%s", "color:red","message: " + this.message); //已被初始化
        },
        //完成了el的绑定
        beforeMount: function() {
           console.group('------beforeMount挂载前状态------');
           console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化
           console.log(this.$el.innerHTML);    
           console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化  
           console.log("%c%s", "color:red","message: " + this.message); //已被初始化  
        },
        mounted: function() {
          console.group('------mounted 挂载结束状态------');
          console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化
          console.log(this.$el);    
          console.log(this.$el.innerHTML);    
          console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化
          console.log("%c%s", "color:red","message: " + this.message); //已被初始化 
        },
        beforeUpdate: function () {
          console.group('beforeUpdate 更新前状态===============》');
          console.log("%c%s", "color:red","el     : " + this.$el);
          console.log(this.$el.innerHTML);
          console.log("%c%s", "color:red","data   : " + this.$data.message); 
          console.log("%c%s", "color:red","message: " + this.message); 
        }
        ,
        updated: function () {
          console.group('updated 更新完成状态===============》');
          console.log("%c%s", "color:red","el     : " + this.$el);
          console.log(this.$el.innerHTML);   
          console.log("%c%s", "color:red","data   : " + this.$data); 
          console.log("%c%s", "color:red","message: " + this.message); 
        },
    //  beforeDestroy: function () {
    //    console.group('beforeDestroy 销毁前状态===============》');
    //    console.log("%c%s", "color:red","el     : " + this.$el);
    //    console.log(this.$el);    
    //    console.log("%c%s", "color:red","data   : " + this.$data); 
    //    console.log("%c%s", "color:red","message: " + this.message); 
    //  },
    //  destroyed: function () {
    //    console.group('destroyed 销毁完成状态===============》');
    //    console.log("%c%s", "color:red","el     : " + this.$el);
    //    console.log(this.$el);  
    //    console.log("%c%s", "color:red","data   : " + this.$data); 
    //    console.log("%c%s", "color:red","message: " + this.message)
    //  }
      });
      
      document.getElementById("btn01").onclick = function(){
      		vm.message="改了";
      }
    

    五、模拟vue的构造函数(部分代码)

    myVue.js

    class MyVue{
    	constructor(obj){
    		//默认值
    		let defaultObj={
    		  data: null,
    		  computed:null,
    		  watch:null,
    		  beforeCreate:function(){
    			
    		  },
    		  created:function(){
    			
    		  },
    		  beforeMount:function(){
    			
    		  },
    		  mounted:function(){
    			
    		  }
    		}
    		for(let key in defaultObj){
    			obj[key]?this[key]=obj[key]:this[key]=defaultObj[key];
    		}
    		
    		//对象创建完毕已经有this了。
    		this.beforeCreate();	
    		//挂载数据:
    		//1)、把传入的data属性的值赋给this
    		if(obj.data){
    			for(let key in this.data){
    				this[key] = obj.data[key];
    			}	
    			this.$data = obj.data;//设置全局变量
    		}
    		//2)、计算属性		
    		if(obj.computed){
    			for(let key in obj.computed){
    				this[key] = obj.computed[key].call(this);
    			}
    		}		
    		//created函数
    		this.created();
    		//检查是否有el属性
    		if(obj.el){
    			this.el = $(obj.el);
    			this.$el = $(obj.el);//设置全局变量
    		}
    		//检查是否有template属性
    		if(this.template){
    			//this.template = obj.template;
    //			动态创建template 里所有的html元素
    		}
    		//beforeMonute
    		this.beforeMount();
    		//用vue对象的数据(属性)替换模板中的内容
    		//1)、替换data中的数据
    		let html = this.el.innerHTML;				
    		for(let key in this.data){
    			//用属性值替换,属性名(页面上用双花括号包起来的)
    			html=html.replace(new RegExp("{{"+key+"}}","g"),this[key]);
    		}	
    		//2)、替换computed中的数据				
    		for(let key in this.computed){
    			//用属性值替换,属性名(页面上用双花括号包起来的)
    			html=html.replace(new RegExp("{{"+key+"}}","g"),this[key]);
    		}	
    		this.el.innerHTML = html;
    		
    		//mounted函数:
    		this.mounted();
    	}
    	
    	addWatch(){
    		
    	}
    	
    	//数据双向绑定
    	
    	//
    }
    
    function $(str){//#box .cls  p
    	if(str.charAt(0)=="#"){
    		return document.getElementById(str.substring(1));
    	}else if(str.charAt(0)=="."){
    		return document.getElementsByClassName(str.substring(1));
    	}else{
    		return document.getElementsByTagName(str);
    	}
    }
    

    html代码:

    <body>

      <div id="app">

        <h1>{{message}}</h1>

        <h1>count:{{count}}</h1>

      </div>

    </body>

    <script type="text/javascript" src="js/myvue.js" ></script>

    <script>

      var vm = new MyVue({

        el: '#app',

        data: {

          message: 'Vue的生命周期',

          age:1

        },

        computed:{

            count:function(){

               return this.age+1;

            }

        },

        beforeCreate: function() {

          console.group('------beforeCreate创建前状态------');

          console.log("%c%s", "color:red" , "el     : " + this.$el); //undefined

          console.log("%c%s", "color:red","data   : " + this.$data); //undefined

          console.log("%c%s", "color:red","message: " + this.message)

        },

        created: function() {

          console.group('------created创建完毕状态------');

          console.log("%c%s", "color:red","el     : " + this.$el); //undefined

          console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化

          console.log("%c%s", "color:red","message: " + this.message); //已被初始化

        },

        //完成了el的绑定

        beforeMount: function() {

           console.group('------beforeMount挂载前状态------');

           console.log("%c%s", "color:red","el     : " + (this.$el)); //已被初始化

           console.log(this.$el);

           console.log(this.$el.innerHTML);   

           console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化 

           console.log("%c%s", "color:red","message: " + this.message); //已被初始化 

        },

        mounted: function() {

          console.group('------mounted 挂载结束状态------');

          console.log("%c%s", "color:red","el     : " + this.$el); //已被初始化

          console.log(this.$el);   

          console.log(this.$el.innerHTML);   

          console.log("%c%s", "color:red","data   : " + this.$data); //已被初始化

          console.log("%c%s", "color:red","message: " + this.message); //已被初始化

        }   

      })

    展开全文
  • Tomcat的生命周期管理简要分析

    千次阅读 2016-12-27 19:14:04
    在上一篇文章中:Tomcat服务器顶层结构和启动过程 对Tomcat的整体架构有了一个大致的了解,这一篇主要是学习一下Tomcat的整个生命周期的管理。Tomcat的生命周期管理使用了观察者模式,使Tomcat的生命周期管理机制...

    在上一篇文章中:Tomcat服务器顶层结构和启动过程 对Tomcat的整体架构有了一个大致的了解,这一篇主要是学习一下Tomcat的整个生命周期的管理。

    Tomcat的生命周期管理使用了观察者模式,使Tomcat的生命周期管理机制设计的非常优雅,在Tomcat启动时,只需要启动一个Server组件,就会启动所有的容器及对应的组件,并且触发这些容器的监听者,完成启动过程的设置。可以说是“一键式”启动的。停止过程也是一样。

    一、观察者模式简单描述

    (1)观察者模式有时被称作:发布/订阅模式,观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

    观察者模式的应用非常广泛,如Java AWT事件模型,Servlet的监听器,Spring事件处理机制以及Tomcat生命周期管理机制等等。

    (2)观察者模式解决的问题

    将一个系统分割成一个一些类相互协作的类有一个不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。

    (3)观察者模式中有3类角色对象:

    1、抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。

    2、具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。

    3、抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。

    4、具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
      
    (4)观察者模式的类图:

    这里写图片描述

    二、Tomcat的生命周期管理相关类

    关于Tomcat的生命周期管理所涉及的相关类主要有:

    (1)Lifecycle:相当于抽象主题角色,所有的容器类与组件实现类都实现了这个接口。如StandardContext

    (2)LifecycleListener:相当于抽象观察者角色,具体的实现类有ContextConfig, HostConfig, EngineConfig类,它们在容器启动时与停止时触发。

    (3)LifecycleEvent:生命周期事件,对主题与发生的事件进行封装。

    (4)LifecycleSupport:生命周期管理的实用类,提供对观察者的添加,删除及通知观察者的方法。(Tomcat release 9.0.x版本中没有用到这个)

    (5)LifecycleException:生命周期异常类。

    三、Lifecycle接口介绍

    组件生命周期方法的通用接口。org.apache.catalina.Lifecycle Tomcat通过Lifecycle接口统一管理生命周期,所有有生命周期的组件都要实现Lifecycle接口,以便提供一致的机制去启动和停止组件。Lifecycle接口内容如下:

    这里写图片描述

    上图中可以看出Lifecycle接口一共做了四件事情:

    (1)定义了13个String类型常量:这些常量信息用于LifecycleEvent事件的type属性中,作用是区分组件发出的LifecycleEvent事件是的状态(如初始化前、启动前、启动中等)。这种设计方法可以让多种状态都发送同一种类型的时间,然后用其中的一个属性类区分状态而不用定义多种事件。

    (2)定义了3个管理监听器的方法:addLifecycleListener、findLifecycleListeners和removeLifecycleListener。分别用来添加、查找和删除LifecycleListener类型的监听器。源码如下图所示:

    这里写图片描述

    (3)定义了4个生命周期的方法:init、start、stop和destory,用于执行生命周期的各个阶段,接口定义如下:

    public void init() throws LifecycleException;
    
    public void start() throws LifecycleException;
    
    public void stop() throws LifecycleException;
    
    public void destroy() throws LifecycleException;

    (4)定义了获取当前和状态的两个方法: getState和getStateName,用来获取当前的状态,getState的返回值LifecycleState是枚举类型,里边列举了生命周期的各个节点,getStateName方法返回String类型的状态的名字。

    完整的Lifecycle 接口定义代码如下:

    
    package org.apache.catalina;
    
    public interface Lifecycle {
    
        public static final String BEFORE_INIT_EVENT = "before_init";
        public static final String AFTER_INIT_EVENT = "after_init";
        public static final String START_EVENT = "start";
        public static final String BEFORE_START_EVENT = "before_start";
        public static final String AFTER_START_EVENT = "after_start";
        public static final String STOP_EVENT = "stop";
        public static final String BEFORE_STOP_EVENT = "before_stop";
        public static final String AFTER_STOP_EVENT = "after_stop";
        public static final String AFTER_DESTROY_EVENT = "after_destroy";
        public static final String BEFORE_DESTROY_EVENT = "before_destroy";
        public static final String PERIODIC_EVENT = "periodic";
        public static final String CONFIGURE_START_EVENT = "configure_start";
        public static final String CONFIGURE_STOP_EVENT = "configure_stop";
    
        public void addLifecycleListener(LifecycleListener listener);
        public LifecycleListener[] findLifecycleListeners();
        public void removeLifecycleListener(LifecycleListener listener);
        public void init() throws LifecycleException;
        public void start() throws LifecycleException;
        public void stop() throws LifecycleException;
        public void destroy() throws LifecycleException;
        public LifecycleState getState();
        public String getStateName();
        public interface SingleUse {
        }
    }

    四、Lifecycle接口默认实现LifecycleBase

    Lifecycle接口的默认实现是org.apache.catalina.util.LifecycleBase ,在LifecycleBase实现类中实现了Lifecycle接口中定义的方法,类结构图如下:

    这里写图片描述

    (1)3个管理监听器的方法

        private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
    
        @Override
        public void addLifecycleListener(LifecycleListener listener) {
            lifecycleListeners.add(listener);
        }
    
        @Override
        public LifecycleListener[] findLifecycleListeners() {
            return lifecycleListeners.toArray(new LifecycleListener[0]);
        }
    
        @Override
        public void removeLifecycleListener(LifecycleListener listener) {
            lifecycleListeners.remove(listener);
        }

    可以看出LifecycleBase定义了一个lifecycleListeners 集合用于保存所有的监听器,然后并定义了添加、删除、查找和执行监听器的方法;

    (2)4个生命周期的方法:init、start、stop和destory

        protected abstract void initInternal() throws LifecycleException;
    
        @Override
        public final synchronized void init() throws LifecycleException {
            //开始的状态必须是LifecycleState.NEW,否则会抛出异常
            if (!state.equals(LifecycleState.NEW)) {
                invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
            }
    
            try {
                //在初始化之前,将状态设置为LifecycleState.INITIALIZING 表示正在初始化中
                setStateInternal(LifecycleState.INITIALIZING, null, false);
                //使用模板的方式进行具体的初始化,该抽象方法是由子类实现的
                initInternal();
                //在初始化之后,将状态设置为LifecycleState.INITIALIZED 表示初始化完成
                setStateInternal(LifecycleState.INITIALIZED, null, false);
            } catch (Throwable t) {
                handleSubClassException(t, "lifecycleBase.initFail", toString());
            }
        }

    这里对四个生命周期,只讨论init方法,其他三种大致相同。

    在init方法中调用了所对应的模板方法initInternal() 该方法并没有具体的实现,而是让子类去具体的实现,因此对于子类来说,执行生命周期的方法就是:initInternal、startInternal、stopInternal、destroyInternal;

    (3)定义了获取当前和状态的两个方法:getState和getStateName

        private volatile LifecycleState state = LifecycleState.NEW;
    
        @Override
        public LifecycleState getState() {
            return state;
        }
    
        @Override
        public LifecycleState getState() {
            return state;
        }
    
        @Override
        public String getStateName() {
            return getState().toString();
        }

    在生命周期相应的方法中已经设置了state的属性,所以通过这两个方法就可以简单的实现获取state。

    五、再谈Tomcat中的观察者模式

    Tomcat中的观察者模式:

    这里写图片描述

    Tomcat中Lifecycle就是抽象的主题。

    然后像StandardEngine、StandardHost、StandardContext、StandardServer这类Container对象,都是具体主题。

    LifecycleListener定义了观察者想要执行的方法。就是前面提到的,如果观察者对主题的某个动作感兴趣,他就会做自己的动作,这个动作就是LifecycleListener里的方法。当然LifecycleListener是一个接口,用户可以定义各种具体的观察者。

    Tomcat对观察者模式做了很好的扩展,他增加了一个LifecycleSupport来代替主题管理多个观察者,把功能模块分得更清晰,LifecycleSupport中定义了一个LifecycleListener的数组。主题中某动作发生时,LifecycleSupport会遍历此数组,对每一个listener调用它们像要做的方法。

    下面的方法就是LifecycleSupport通知各个LifecycleListener某事件发生了。

        /**
         * Notify all lifecycle event listeners that a particular event has
         * occurred for this Container.  The default implementation performs
         * this notification synchronously using the calling thread.
         * 
         * @param type Event type
         * @param data Event data
         */
        public void fireLifecycleEvent(String type, Object data) {
    
            LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
            LifecycleListener interested[] = listeners;
            for (int i = 0; i < interested.length; i++)
                interested[i].lifecycleEvent(event);
    
        }

    Tomcat中将事件定义为LifecycleEvent

        /**
         * Construct a new LifecycleEvent with the specified parameters.
         *
         * @param lifecycle Component on which this event occurred
         * @param type Event type (required)
         * @param data Event data (if any)
         */
        public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
            super(lifecycle);
            this.type = type;
            this.data = data;
        }

    事件有一个属性type,用来标明事件的类型。

    也就是说Tomcat中观察者模式流程:
    1、将观察者listener增加到LifecycleSupport的listener数组中
    2、当container(主题)做某些动作的时候,会生成一个LifecycleEvent对象,这个对象标明当前这个动作是一个什么事件,然后LifecycleSupport会通知listener数组中的每一个观察者该事件的发生。
    3、listener会根据LifecycleEvent判断事件的类型,完成相应的动作。


    参考文章:

    1、https://my.oschina.net/u/227422/blog/66213
    2、http://www.cnblogs.com/chenying99/archive/2012/09/05/2671199.html

    展开全文
  • Servlet的生命周期

    万次阅读 多人点赞 2019-06-02 17:36:53
    Servlet的生命周期 servlet的生命周期就是从servlet出现到销毁的全过程。主要分为以下几个阶段: 加载类—>实例化(为对象分配空间)—>初始化(为对象的属性赋值)—>请求处理(服务阶段)—>销毁 服务器启动...
  • 生命周期 生命周期执行顺序 Awake 触发时机:当脚本实例被创建时调用 用途:用于游戏对象的初始化 注意:Awake的执行是早于所有脚本的Start函数的,生命周期内只执行一次 OnEnable 触发时机:当对象变为可用或激活...
  • vue生命周期是什么?

    千次阅读 多人点赞 2019-03-25 23:29:25
    我们知道vue是一个构建数据驱动的web界面的渐进式框架,那么vue生命周期是什么呢? vue的生命周期是什么? vue生命周期是指vue实例对象从创建之初到销毁的过程,vue所有功能的实现都是围绕其生命周期进行的,在...
  • .NET ASP.NET 页生命周期概述

    千次阅读 2019-05-07 10:47:49
    ASP.NET 页生命周期概述 ASP.NET 页运行时,此页将经历一个生命周期,在生命周期中将执行一系列处理步骤。 这些步骤包括初始化、实例化控件、还原和维护状态、运行事件处理程序代码以及进行呈现。 了解页生命周期...
  • 软件工程:软件开发生命周期 (SDLC)

    万次阅读 2019-02-11 17:28:30
    软件构建的基本概念之一 - 软件开发生命周期模型。或者只是SDLC模型。SDLC - 是一个连续的过程,从决定启动项目的那一刻开始,并在它完全从开发中移除的那一刻结束。没有一个单一的SDLC模型。它们分为主要组,每组都...
  • 软件项目的全生命周期

    万次阅读 多人点赞 2018-10-12 16:52:05
    就职于软件行业的人,无论是销售、售前、技术还是财务一定都会接触到关于项目运作相关的工作,不同职位的员工对于项目的关注点也大不相同,财务人员关注项目的收款节点;销售人员关注项目的商务关系及前期引导;...
  • activity生命周期(这篇足够了)

    万次阅读 多人点赞 2017-12-07 14:35:02
    activity生命周期(这篇足够了) 摘要 做安卓开发已经4年多了,所接触的知识点也比较零散,在这里记录一下android方面的知识点,方便自己以后复习,有什么不足的,以及错误的欢迎拍砖。 activity ...
  • 典型的六种项目生命周期模型

    千次阅读 2019-10-30 13:50:08
    瀑布模型 强调开发工作(计划、设计、开发、测试、...每个周期分为四个阶段:制定计划、风险分析、实施工程、客户评估;强调的是产品从小到大,不断改进,不断风险分析的过程,特别适合于庞大而复杂的、高风险的系统...
  • Page({ // 页面第一次渲染使用的初始数据 data: { text: "This is page data." }, onLoad: function(options) { // 生命周期回调—监听页面加载 }, onShow: function() { ... // 生命周期回调—监听页面初次
  • import React from 'react'; import logo from './logo.svg'; import './App.css'; class App extends React.Component{ constructor(props){ super(props) this.state = { msg:'第一次的消息' ...
  • Spring中bean的作用域与生命周期

    万次阅读 多人点赞 2017-06-17 22:29:18
    在Spring中,那些组成应用程序的主体及由Spring IoC容器所管理的对象,被称之为bean。简单地讲,bean就是由IoC容器初始化、装配及管理的对象,除此之外,bean就与应用程序中的其他对象没有什么区别了。...
  • 问:什么是软件生命周期模型?试比较瀑布模型,快速原型模型,增量模型和螺旋模型的优缺点,说明每种模型的适用范围。 答:软件的生命周期由软件定义,软件开发,运行维护(软件维护)3时期组成,每时期又...
  • 软件生命周期的八个阶段

    万次阅读 多人点赞 2018-04-25 16:07:47
    我们在软件的开发和维护过程中会遇到一系列严重的问题,比如软件开发的成本和进度估计的不准,用户对已经完成开发的软件不满意、用户需求变更、软件产品...软件开发主要分为以下几个阶段1、问题定义确定好要解决的问...
  • 组件的生命周期一般分为这 4 个阶段:创建阶段、实例化阶段、运行(更新)阶段、销毁阶段。下面对各个阶段分别进行介绍。 创建阶段:该阶段主要发生在创建组件类的时候,在这个阶段中会初始化组件的属性类型和默认...
  • 软件生命周期模型——瀑布模型

    万次阅读 2018-06-09 11:03:49
    模型概述 瀑布模型是一经典的软件生命周期模型,也叫预测型生命周期、完全计划驱动型生命周期。在这模型里,在项目生命周期的尽早时间,要确定项目范围及交付此范围所需的时间和成本。 在这模型里,项目启动...
  • 如何搭建用户生命周期模型

    千次阅读 2019-07-02 14:20:04
    用户的生命周期,简单来说就是:用户从开始接触产品到离开产品的整个过程。 根据上图可知,用户的生命周期主要分为5个阶段:导入期、成长期、成熟...但是,回到最初的起点,我们怎么才能搭建一个用户生命周期模型来...

空空如也

1 2 3 4 5 ... 20
收藏数 791,441
精华内容 316,576
关键字:

生命周期