您的位置:首页 > 大数据 > 人工智能

dailynote1.29(每天进步一点,一定会有机会做项目的)

2018-01-29 17:49 211 查看
先学js在chrome上的调试呢,还是搞bookstore呢?

先搞bookstore吧;

AOP

AOP:面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,我们知道,面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代码的复杂程度,使类可重用。      但是人们也发现,在分散代码的同时,也增加了代码的重复性。什么意思呢?比如说,我们在两个类中,可能都需要在每个方法中做日志。按面向对象的设计方法,我们就必须在两个类的方法中都加入日志的内容。也许他们是完全相同的,但就是因为面向对象的设计让类与类之间无法联系,而不能将这些重复的代码统一起来。
   也许有人会说,那好办啊,我们可以将这段代码写在一个独立的类独立的方法里,然后再在这两个类中调用。但是,这样一来,这两个类跟我们上面提到的独立的类就有耦合了,它的改变会影响这两个类。那么,有没有什么办法,能让我们在需要的时候,随意地加入代码呢?这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。(

作者:知乎用户

链接:https://www.zhihu.com/question/24863332/answer/48376158

.)

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调 

2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用 

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能 

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次

拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。

过滤器:是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符。主要为了减轻服务器负载,减少压力。

(https://www.zhihu.com/question/24863332)

IoC和AOP这两个缩写总是一起出现。在形式上,两者同为三个字母的缩写,而且第二个字母都是O,有对仗美;在性质上,两者同为Spring的核心技术和特色,是最常被提起的概念。

但与面向切面编程AOP真正对应的,是OOP,即面向对象编程。未说面向切面,先说面向过程。面向对象侧重静态,名词,状态,组织,数据,载体是空间;  面向过程侧重动态,动词,行为,调用,算法,载体是时间;   这两者,运行于不同维度,本不互相冲突,理应携手合作,相互配合。   所以,web项目中的controller,service,dao等各层组件,有行为无状态,有方法无属性,即使有属性,也只是对下一层组件的持有;  所以,web项目中的entity,dto等各种实体,有状态无行为,有属性无方法,即使有方法,也只是getter/setter等,围着状态打转;
  反倒是我们刚学「面向对象」时说的「既有眼睛又会叫」的小狗那种状态行为俱全的对象,基本见不到了。   程序需要状态,但对象不需要状态。  如果对象有了状态,就会引发烦人的多线程问题,在集群环境下更是麻烦。  程序的状态,统一由数据库,缓存,任务队列这些外部容器来容纳,在处理时,仅仅在对象的方法中以局部变量的面目偶尔出现,被封在线程内部,朝生夕灭,任由回收。   基于Java语言的web开发,本质是用面向对象的组织,面向过程的逻辑,来解决问题。应用实践中灵活具体,不拘泥,不教条。   但仍会遇到一种麻烦,即假如一个流程分三个步骤,分别是X,A,Y,另一个流程的三个步骤是X,B,Y。
 写在程序里,两个方法体分别是XAY和XBY,显然,这出现了重复,违反了DRY原则。  你可以把X和Y分别抽成一个方法,但至少还是要写一条语句来调用方法,xAy,xBy,重复依然存在。   如果控制反转来处理这问题,将采用模板方法的模式,在抽象父类方法体中声明x?y,其中?部分为抽象方法,由具体子类实现。  但这就出现了继承,而且调用者只能调用父类声明的方法,耦合性太强,不灵活。  所以,我们常看到,只有那些本来就是调用者调用父类声明的方法的情况,比如表现层,或者本来就不用太灵活,比如只提供增删改查的持久层,才总出现抽象父类的身影。
  具体Controller is-a 抽象Controller,具体Dao is-a 抽象Dao,这大家都能接受。  但除了在抽象Controller、抽象Dao中固定的步骤之外,我们就不需要点别的吗?  比如在某些Controller方法运行之前做点什么,在某些Dao方法运行之前之后做点什么?  而且最好能基于配置,基于约定,而不是都死乎乎硬编码到代码里。   这些需求,基本的编程手段就解决不了了。  于是乎,面向切面横空出世。  《Spring3.x企业应用开发实战》(下称《3.x》)第6章写道:  AOP是OOP的有益补充。
 Spring实现的AOP是代理模式,给调用者使用的实际是已经过加工的对象,你编程时方法体里只写了A,但调用者拿到的对象的方法体却是xAy。   x和y总还是需要你来写的,这就是增强。  x和y具体在什么时候被调用总还是需要你来规定的,虽然是基于约定的声明这种简单的规定,这就是切点。  《EXPERT ONE ON ONE J2EE DEVELOPMENT WITHOUT EJB》第8章、《Spring实战》第4章:  增强(advice,另译为通知,但《3.x》作者不赞成):在特定连接点执行的动作。  切点(pointcut):一组连接点的总称,用于指定某个增强应该在何时被调用。
 连接点(join point):在应用执行过程中能够插入切面的一个点。(我注:就是抽象的「切点」声明所指代的那些具体的点。)  切面(aspect):通知(即增强)和切点的结合。  其他概念不赘,如果有兴趣可以自行去翻书,我每次看到这些东西都很头大。   用人话说就是,增强是「干啥」,切入点是「啥时候干」。  生活中例子如端碗-吃饭-放筷子,端碗-吃面-放筷子,你只要定义好端碗和放筷子,并声明在吃点啥之前之后调用它们,业务方法只要实现吃饭、吃面就行了,以后想加个吃饺子也很方便。  生产中例子如事务、安全、日志(*),用声明的方式一次性配好,之后漫漫长夜专注于写业务代码就行了,不再为这些事而烦。
 《Spring实战》第4章:  散布于应用中多处的功能(日志、安全、事务管理等)被称为横切关注点。  把横切关注点与业务逻辑分离是AOP要解决的问题。  *:但《Spring3.x企业应用开发实战》第6章说:  很多人认为很难用AOP编写实用的程序日志。笔者对此观点非常认同。(我注:我也认同)   总之,面向切面的目标与面向对象的目标没有不同。  一是减少重复,二是专注业务。  相比之下,面向对象是细腻的,用继承和组合的方式,绵绵编织成一
4000
套类和对象体系。  而面向切面是豪放的,大手一挥:凡某包某类某开头的方法,一并如斯处理!
  《Javascript DOM编程艺术》说,dom是绣花针,innerHTML是砍柴斧。  我看面向对象和面向切面,也可做如是观。   没有依赖注入,面向切面就失去立足之本。  没有面向切面,依赖注入之后也只好在各个方法里下死力气写重复代码,或者搞出来一个超级复杂的抽象基类。  同时有了这两者,才真正能履行拆分、解耦、模块化、约定优于配置的思想,才真正能实现合并重复代码、专注业务逻辑的愿望。   不过,这面向切面不是Spring的专利,Java Web开发中最基本的Filter,就是一层一层的切面,突破了之后才能触及Servlet这内核。
 但Filter过于暴力粗放,只能运行在Servlet之外而不能在之内,能上不能下,稍微细一点的批处理它就不行了,而Spring的AOP可以。  (Struts2的Intercepter也算,关于这就不多说了,如感兴趣可看《Struts2技术内幕》第8章Intercepter部分)  从理论上说,Filter和Spring AOP前者是责任链模式(Struts2 Intercepter也是),后者是代理模式,性质不同,但从「层层包裹核心」的共同特点看,是一致的。   所以无论是宽是窄,只要你遇到了「好多方法里都有重复代码好臭哇呀」的情况(关于代码的坏气味可以参考《重构》),而又无法应用策略、装饰器、模板方法等模式,就考虑AOP吧!
 毕竟虽然Spring的书籍里讲到AOP就连篇累牍、名词繁多、配法多样、望而生畏,但具体写起来还是非常简单的。  (不过,如果能用「绣花针」OOP的设计模式实现,还是不建议轻易动用AOP这「劈柴刀」,不得已才用之。关于设计模式,推荐《Java与模式》一书) 

注解:

所谓注解,就是给代码添加一些元数据,描述信息,这些描述信息可以在允许时通过API获取到,然后针对这些注解进行一些操作,比如哪些类是TestCase,类的哪些方法是要执行的测试,比如根据注解进行依赖注入。  

相比使用单独的XML来描述这些元数据,使用注解要简单些,和代码在一起也更好维护。相比使用继承(如TesCase)或者方法前缀的约定(如testXXX是测试方法)要灵活些。  

一些插件机制就是通过注解提供插件的元数据,在加载类后扫描所以带该注解的类就可以找到插件,减少了配置的麻烦。

反射机制:

作者:郭无心

链接:https://www.zhihu.com/question/24304289/answer/76541818

来源:知乎

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力。通过这种能力可以彻底的了解自身的情况为下一步的动作做准备。下面具体介绍一下java的反射机制。 Java的反射机制的实现要借助于4个类:class,Constructor,Field,Method;

其中class代表的时类对 象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象。通过这四个对象我们可以粗略的看到一个类的各个组 成部分。Java反射的作用:在Java运行时环境中,对于任意一个类,可以知道这个类有哪些属性和方法。对于任意一个对象,可以调用它的任意一个方法。这种动态获取类的信息以及动态调用对象的方法的功能来自于Java 语言的反射(Reflection)机制。Java 反射机制主要提供了以下功能在运行时判断任意一个对象所属的类。

在运行时构造任意一个类的对象。

在运行时判断任意一个类所具有的成员变量和方法。

在运行时调用任意一个对象的方法

反射的常用类和函数:Java反射机制的实现要借助于4个类:Class,Constructor,Field,Method;其中class代表的是类对象,Constructor-类的构造器对象,Field-类的属性对象,Method-类的方法对象,通过这四个对象我们可以粗略的看到一个类的各个组成部分。其中最核心的就是Class类,它是实现反射的基础,它包含的方法我们在第一部分已经进行了基本的阐述。应用反射时我们最关心的一般是一个类的构造器、属性和方法,下面我们主要介绍Class类中针对这三个元素的方法:1、得到构造器的方法 

Constructor getConstructor(Class[] params) -- 获得使用特殊的参数类型的公共构造函数, 

 

Constructor[] getConstructors() -- 获得类的所有公共构造函数 

 

Constructor getDeclaredConstructor(Class[] params) -- 获得使用特定参数类型的构造函数(与接入级别无关) 

 

Constructor[] getDeclaredConstructors() -- 获得类的所有构造函数(与接入级别无关) 

2、获得字段信息的方法Field getField(String name) -- 获得命名的公共字段 

 

Field[] getFields() -- 获得类的所有公共字段 

 

Field getDeclaredField(String name) -- 获得类声明的命名的字段 

 

Field[] getDeclaredFields() -- 获得类声明的所有字段 

3、获得方法信息的方法Method getMethod(String name, Class[] params) -- 使用特定的参数类型,获得命名的公共方法 

 

Method[] getMethods() -- 获得类的所有公共方法 

 

Method getDeclaredMethod(String name, Class[] params) -- 使用特写的参数类型,获得类声明的命名的方法 

 

Method[] getDeclaredMethods() -- 获得类声明的所有方法 

在程序开发中使用反射并结合属性文件,可以达到程序代码与配置文件相分离的目的如果我们想要得到对象的信息,一般需要“引入需要的‘包.类’的名称——通过new实例化——取得实例化对象”这样的过程。使用反射就可以变成“实例化对象——getClass()方法——得到完整的‘包.类’名称”这样的过程。正常方法是通过一个类创建对象,反射方法就是通过一个对象找到一个类的信息。

使用反射机制也可以取得类之中的构造方法,这个方法在Class类之中已经明确定义了:

以下两个方法

取得一个类的全部构造:public Constructor<?>[] getConstructors() throws

  SecurityException

取得一个类的指定参数构造:public Constructor<T> getConstructor(Class<?>...

  parameterTypes) throws NoSuchMethodException, SecurityException

JFinal的指令:

#include 指令

    include指令用于将外部模板内容包含进来,被包含的内容会被解析成为当前模板中的一部分进行使用,

#render 指令

    render指令在使用上与include指令几乎一样,同样也支持无限量传入赋值表达式参数,主要有两点不同:

render指令:

render指令支持动态化模板参数,例如:#render(temp),这里的temp可以是任意表达式,而#include指令只能使用字符串常量:#include(“abc.html”)

render指令中#define定义的模板函数只在其子模板中有效,在父模板中无效,这样设计非常有利于模块化

引入 #render 指令的核心目的在于支持动态模板参数。

#define 指令:

#define指令是模板引擎主要的扩展方式之一,define指令可以定义模板函数(Template Function)。

通过define指令,可以将需要被重用的模板片段定义成一个个的 template function,在调用的时候可以通过传入参数实现千变万化的功能。

在此给出使用define指令实现的layout功能,首先创建一个layout.html文件,其中的代码如下:

#define layout()

<html>

  <head>

    <title>JFinal俱乐部</title>

  </head>

  <body>

    #@content()

  </body>

</html>

#end

 以上代码中通过#define layout()定义了一个名称为layout的模板函数,定义以#end结尾,其中的#@content()表示调用一个名为content的模板函数。

特别注意:模板函数的调用比指令调用多一个@字符,是为了与指令调用区分开来。

接下来再创建一个模板文件,如下所示:

#include("layout.html")

#@layout()

 

#define content()

<div>

   这里是模板内容部分,相当于传统模板引擎的 nested 的部分

</div>

#end
上图中的第一行代码表示将前面创建的模板文件layout.html包含进来,第二行代码表示调用layout.html中定义的layout模板函数,而这个模板函数中又调用了content这个模板函数,该content函数已被定义在当前文件中,简单将这个过程理解为函数定义与函数调用就可以了。注意,上例实现layout功能的模板函数、模板文件名称可以任意取,不必像velocity、freemarker需要记住 nested、layoutContent这样无聊的概念。

    通常作为layout的模板文件会在很多模板中被使用,那么每次使用时都需要#include指令进行包含,本质上是一种代码冗余,可以在configEngine(Engine me)方法中,通过me.addSharedFunction("layout.html")方法,将该模板中定义的所有模板函数设置为共享的,那么就可以省掉#include(…),通过此方法可以将所有常用的模板函数全部定义成类似于共享库这样的集合,极大提高重用度、减少代码量、提升开发效率。
JFinal Template Engine彻底消灭掉了layout、nested、macro这些无需有的概念,极大降低了学习成本,并且极大提升了扩展能力。模板引擎本质是一门程序语言,任何可用于生产环境的语言可以像呼吸空气一样自由地去实现layout这类功能。

模板函数的调用比指令调用多一个@字符,是为了与指令调用区分开来。

数组存取:array[i](Map被增强为额外支持 map[key]的方式取值,key必须为String型)

taglib指令:

指定引入标签库描述符文件的URI,predix:前缀
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  笔记