惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
SecWiki News
SecWiki News
酷 壳 – CoolShell
酷 壳 – CoolShell
爱范儿
爱范儿
量子位
M
MIT News - Artificial intelligence
GbyAI
GbyAI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
TaoSecurity Blog
TaoSecurity Blog
博客园 - 【当耐特】
H
Heimdal Security Blog
腾讯CDC
The Last Watchdog
The Last Watchdog
Security Archives - TechRepublic
Security Archives - TechRepublic
Hacker News: Ask HN
Hacker News: Ask HN
S
Schneier on Security
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
博客园 - 司徒正美
Recent Commits to openclaw:main
Recent Commits to openclaw:main
C
Cybersecurity and Infrastructure Security Agency CISA
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Full Disclosure
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
Engineering at Meta
Engineering at Meta
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
T
Threatpost
月光博客
月光博客
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
雷峰网
雷峰网
T
Troy Hunt's Blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The Cloudflare Blog
D
DataBreaches.Net
O
OpenAI News
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
小众软件
小众软件
V
Vulnerabilities – Threatpost
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
T
The Exploit Database - CXSecurity.com
Martin Fowler
Martin Fowler
美团技术团队
P
Privacy International News Feed

博客园 - evilyzou

scala 的List foldLeft用法 Circumflex Scala中的Either的两个子类(Left,Right)的简单用法 Scala中的一些特殊字符用法 Scala中的PartialFunction在Lift当中的NamedPF应用 scala的DynamicVariable用法 SBT和IDEA 开发scala web程序 使用Sbt(一) scalatra web框架安装指南 ASP.NET MVC: Do You Know Where Your TempData Is? 使用IntelliJ IDEA, Maven and the jetty plugin调试web应用程序 Scala GraphViz DOT Parser Scala Standard library Scala 一些基本的语法 Scala 相关的资源和Blog Lift2.0发布 Linux 汇编语言开发指南 Linux2.6内核启动流程学习 [导入]C#强化系列文章五:动态代码的使用(反射和动态生成类) [导入]C#强化系列文章七:序列化和反序列化
Lift当中的AnyVarTrati源码解析
evilyzou · 2010-08-24 · via 博客园 - evilyzou

在Lift2.0当中,AnyVarTrait是一个非常重要的trait,很多重要的像RequestVar,SessionVar都是继续该接口的,

首先看下大致接口代码

abstract class AnyVar[T, MyType <: AnyVar[T, MyType]](dflt: => T) extends AnyVarTrait[T, MyType] {
  self: MyType =>

  protected def calcDefaultValue: T = dflt
}

/**
 * Abstract a request or a session scoped variable.
 */
trait AnyVarTrait[T, MyType <: AnyVarTrait[T, MyType]] extends PSettableValueHolder[T] with HasCalcDefaultValue[T] {

AnyVarTrait继承了PSettableValueHolder,它的接口是:

trait ValueHolder {
  type ValueType
    def is: ValueType
  def get: ValueType
}

trait SettableValueHolder extends ValueHolder {
  def set(in: ValueType): ValueType
}

trait PValueHolder[T] extends ValueHolder {
 type ValueType = T
  // def manifest: Manifest[T]
}


trait PSettableValueHolder[T] extends PValueHolder[T] with SettableValueHolder

}
}

PSettableValueHolder主要是实现了类似于get,set的这样的方法,比较简单,写一个比较简单的实现PSettableValueHolder的例子:

class Example

trait ValueHolder{
  type ValueType
  def is: ValueType
  def get: ValueType
}

trait SettableValueHolder extends ValueHolder{
   def set(in: ValueType): ValueType
}

trait PValueHolder[T] extends ValueHolder{
  type ValueType = T
}


trait PSettableValueHolder[T] extends PValueHolder[T] with SettableValueHolder

class TestPSettableValueHolder[T] extends PSettableValueHolder[T]
{
  protected var testVal: T=_

  def set(in: T):T ={
    testVal=in
    in
  }

  def get:T={
    testVal
  }

   def is:T={
    testVal
  }
}

object Test{
  def main(args: Array[String]){
     val test=new TestPSettableValueHolder[String]
     test.set("Test22")
     println(test.get)

  }
}

需要重载的方法:

protected lazy val name = VarConstants.varPrefix+getClass.getName+"_"+__nameSalt
  protected def findFunc(name: String): Box[T]
  protected def setFunc(name: String, value: T): Unit
  protected def clearFunc(name: String): Unit
  protected def wasInitialized(name: String): Boolean


  protected def calcDefaultValue: T

  /**
   * A non-side-effecting test if the value was initialized
   */
  protected def testWasSet(name: String): Boolean

  protected def __nameSalt = ""

  type CleanUpParam

  /**
   * Different Vars require different mechanisms for synchronization.  This method implements
   * the Var specific synchronization mechanism
   */
  def doSync[F](f: => F): F

实现了PSettableValueHolder[T] trait的方法:

/**
   * The current value of the variable
   */
  def is: T = doSync {
    findFunc(name) match {
      case Full(v) => v
      case _ => val ret = calcDefaultValue
        testInitialized
        apply(ret)
        // Use findFunc so that we clear the "unread" flag
        findFunc(name) match {
          case Full(v) => v
          case _ => ret
        }
    }
  }

  private def testInitialized: Unit = doSync {
    if (!wasInitialized(name)) {
      registerCleanupFunc(_onShutdown _)
    }
  }

  /**
   * Shadow of the 'is' method
   */
  def get: T = is

  /**
   * Shadow of the apply method
   */
  def set(what: T): T = apply(what)

该trait的apply实现:

/**
   * Set the session variable
   *
   * @param what -- the value to set the session variable to
   */
  def apply(what: T): T = {
    testInitialized
    setFunc(name, what)
    what
  }

最后一个该trait非常重要的方法 :在该var的生命周期内去修改它的Value:

  /**
   * Change the value of the Var for the lifespan of the function
   */
  def doWith[F](newVal: T)(f: => F): F = {
    val old = findFunc(name)
    setFunc(name, newVal)
    try {
      f
    } finally {
      old match {
        case Full(t) => setFunc(name, t)
        case _ => clearFunc(name)
      }
    }
  }

再来看下该trait的具体实现:SessionVar和RequestVar

SessionVar,看下他的几个主要实现AnyVarTrait的实现:

 override protected def findFunc(name: String): Box[T] = S.session match {
    case Full(s) => s.get(name)
    case _ =>
      if (showWarningWhenAccessedOutOfSessionScope_?)
      logger.warn("Getting a SessionVar "+name+" outside session scope") // added warning per issue 188

      Empty
  }

  override protected def setFunc(name: String, value: T): Unit = S.session match {
    case Full(s) => s.set(name, value)
    case _ =>
      if (showWarningWhenAccessedOutOfSessionScope_?)
      logger.warn("Setting a SessionVar "+name+" to "+value+" outside session scope") // added warning per issue 188
  }

      /**
   * Different Vars require different mechanisms for synchronization.  This method implements
   * the Var specific synchronization mechanism
   */
  def doSync[F](f: => F): F = S.session match {
    case Full(s) =>
      // lock the session while the Var-specific lock object is found/created
      val lockName = name + VarConstants.lockSuffix
      val lockObj = s.synchronized {
        s.get[AnyRef](lockName) match {
          case Full(lock) => lock
          case _ => val lock = new AnyRef
          s.set(lockName, lock)
          lock
        }
      }

      // execute the query in the scope of the lock obj
      lockObj.synchronized {
        f
      }
    case _ => f
  }

RequestVar的实现:

override protected def findFunc(name: String): Box[T] = RequestVarHandler.get(name)

  override protected def setFunc(name: String, value: T): Unit = RequestVarHandler.set(name, this, value)

  override protected def clearFunc(name: String): Unit = RequestVarHandler.clear(name)

  override protected def wasInitialized(name: String): Boolean = {
    val bn = name + VarConstants.initedSuffix
    val old: Boolean = RequestVarHandler.get(bn) openOr false
    RequestVarHandler.set(bn, this, true)
    old
  }

  /**
   * Different Vars require different mechanisms for synchronization.  This method implements
   * the Var specific synchronization mechanism
   */
  def doSync[F](f: => F): F = f // no sync necessary for RequestVars... always on the same thread