CDI server decorstors intercepters scope EL eventmodel

一、EL
1.概述;
EL是JSP内置的表达式语言,用以访问页面的上下文以及不同作用域中的对象 ,
取得对象属性的值,或执行简单的运算或判断操作。EL在得到某个数据时,会自动进行数据类型的转换。
使用EL表达式输出数据时,如果有则输出数据,如果为null则什么也不输出。
2.语法:

  • EL表达式总是放在{}中,而且前边有一个:
  • {}
  • 获取对象的属性值可以直接通过“对象.属性名”:${user.name};

    注意:这里的属性名是get和set方法对应的属性值,并不是对象中的变量名。

  • 获取对象的属性也可以通过“对象[“属性名”]”:${user["name"]}
  • 获取Map中属性时可以以直接通过属性的key:({map.key},){map[key]}
  • 在指定域中获取属性:
    在EL表达式中如果我们直接使用属性名如:user<code>pageScoperequestScopesessionScopeapplicationScope</code><code>
  • { pageScope .user }:当前页面
    ({requestScope.user}</code>:当前请求 <code>){sessionScope.user}:当前会话
    ${sessionScope.user}:当前应用
    3.EL中包含11个隐含对象,这些对象可以在EL表达式中直接使用:
  • pageContext,和JSP中的pageContext功能一样

  • 请求域:pageScope/requestScope/sessionScope/applicationScope
  • 请求参数,参数对象主要用于获取get或post请求中的参数:
    param:获取指定的请求参数,({param.username}</code> paramValues:获取请求参数数组,如:<code>){paramValues.sport[1]}
  • 其他:header/headerValues/initParam/cookie

3.EL中包含11个隐含对象,这些对象可以在EL表达式中直接使用:

  • pageContext,和JSP中的pageContext功能一样
  • 请求域:pageScope/requestScope/sessionScope/applicationScope
  • 请求参数,参数对象主要用于获取get或post请求中的参数:
    • param:获取指定的请求参数,${param.username}
    • paramValues:获取请求参数数组,如:${paramValues.sport[1]}
  • 其他:header/headerValues/initParam/cookie

4.EL支持数学运算和逻辑运算:

  • 加减乘除:${17+5} => 22
  • 取余%或mod:${17%5} => 2
  • 比较运算符>,<,==,!=,<=,>=,eq,ne,lt,gt,le,ge:3>5
  • {3 gt 5} =>false
  • 逻辑比较 &&或and,!或not,||或or,empty:${!true} => false
     

二、SpEL

1)Spring框架的表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。
SpEL 为 bean 的属性进行动态赋值提供了便利.

2)语法:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL。


3)运用范围:

  • a. 对 bean 进行引用,调用属性值:#{book.name}
  • b.调用方法以及引用对象中的属性
    • 引用方法:#{dog.run()},引用静态方法:#{T(java.lang.Math).PI}
    • 引用对象的属性:#{user.name}
  • c.计算表达式的值
    • 加减乘除:#{counter.total + 40},#{T(java.lang.Math).PI * 2}
    • 加号作为字符串连接符:#{user.name + ‘ ‘ + user.address}
    • 比较运算符(>,<,=,>=,<=,==,lt,gt,eq,le,ge):
    • #{counter.total == 100},#{counter.total le 1000}
    • if-else条件判断,三元运算符:
    • #{user.name==‘Tom‘ ? ‘Jess‘}
  • d.正则表达式的匹配(matches)
    • #{user.name matches ‘^[a-zA-Z0-9_-]{4,16}$‘}
  • e.字面量的表示:
    • #{5},#{89.7},#{1e4},#{false}
    • 可使用单/双引号作为字符串表达符号:#{‘Chuck‘},#{"Chuck"}

三、Decorator:

1.Decorator 设计模式的特点:

Decorator 设计模式正如毛胚房的装修,不会改变原毛胚房的基本框架,只是增加新的外观、功能等,且随着时间的推移,可以不断的实施装修工程:增加新的家具、根据心情换换新鲜的墙纸等等。在面向对象的程序设计中,扩展系统的原有功能也可以采用继承、组合的方式。继承也不会改变毛胚房(父类),但是由于装修工程的复杂和很多不可预测的改变,比如不同墙纸和地板样式的组合数量简直无法想想,难道我们要为每一种组合都定义一个子类吗?显然这是不现实的,即通过继承的方式来应对未来的功能和外观改变通常是吃力不讨好的事情。组合的方式也不可取,因为这要求不断的修改父类的结构,相当于对毛胚房大动干戈,房屋的可维护性和可靠性就大大降低了。

让我们回顾一下设计模式的重要原则:Classes should be open for extenstion, but closed for modification。Decorator 设计模式很好的诠释了这个原则。

2.CDI 对 Decorator 设计模式的支持:

Decorator 设计模式虽然降低了需求变更对软件开发的影响,但是通过层层包装,即层层 new 操作创建对象的方式不够优雅。CDI 容器可以管理组件的生命周期,在大部分情况下我们无须通过 new 操作创建所需要的对象。CDI 中的 Decorator/Delegate 注解很大程度上简化了 Decorator 设计模式的代码编写量,比如实现上面相同的功能,借助于 CDI,就无须 RoomDecorator 这个抽象类了,所有的 Decorator 类直接实现 Room 接口并使用注解声明为 Decorator 即可

3.总结:

Decorator 设计模式简单而精巧,它其实是 Unix 哲学的体现:每一个应用程序都尽力做好自己,然后通过应用程序之间的协作完成更复杂的任务,正如 shell 的管道符的作用。从复杂应用程序框架设计的角度看,Decorator 设计模式也降低了模块之间的耦合度,而 CDI 更进了一步,借助于容器和类型安全的组件模型,简化了 Decorator 模式的应用,同时消除了某些潜在的运行时异常,也就是说,CDI 之上的 Decorator 设计模式能够帮助构建更加安全的复杂应用。

四、Interceptor

1.拦截器综述:

拦截器的功能是定义在Java拦截器规范。

拦截器规范定义了三种拦截点:

  • 业务方法拦截,
  • 生命周期回调侦听,
  • 超时拦截(EJB)方法。

五、Producer

CDI是为解耦而生.如Spring主要用途是AOP.IOC(DI),而CDI除了DI外,AOP功能也是有的.从实际使用上来看,CDI比Spring功能更丰富,更灵活,其代价也是有的,学习成本相对spring较高.

1.CDI致力于松耦合,强类型.

实现松散耦合的三种方式:

  • 部署时候的多态选择,@alternatives
  • producer methods在运行时的多态.
  • 上下文相关的生命周期管理与bean生命周期解耦。

这些技术使客户端和服务器的松散耦合服务。客户端不再是紧密地绑定到一个接口的一个实现,也不需要管理生命周期实现。这种方法允许有状态的对象当作服务交互。松散耦合使系统更具活力。在以前,框架总是牺牲了类型安全(尤其是通过使用XML描述符,Spring2.5)。

CDI提供了三个额外的重要措施,进一步松耦合:

  • 在业务逻辑层用拦截器技术解耦.
  • 修饰符(注解)可以用来分离一些业务问题
  • 用CDI EVENT技术进行解耦事件生产者与消费者.
原文地址:https://www.cnblogs.com/lijianxuan/p/10808233.html