Leo Wang's Notepad

技术

理解Spring中的DI和AOP

问题的提出

Spring中的依赖注入(DI)为何而生?

下面这篇日语文章提到,所有的Web应用都需要考虑到下面三个问题。

Spring MVCの概要を理解する

1)对象的生命周期问题。

假设你用Servlet来接收用户的访问请求,有一个用户需要访问一个页面,你就需要一个线程来负责处理这个请求,并调用某个业务逻辑(比如调用一个UserService的实例)。如果处理不当,每新增一个用户就实例化一个业务逻辑(new一个UserService的实例),随着访问用户的增多,就会给系统带来大量垃圾回收负担,以及内存消耗的问题。为了防止这种情况发生,就需要把业务逻辑的部分设计为Singleton的,这样就不会每次都新增一个实例。

2)松耦合问题。

为了实现Web程序中的松耦合,即让一个类与另一个类不是那么的紧密结合,通常需要接口(Interface)来实现。但是单存的利用Interface并不能实现松耦合。还需要利用一些技巧,比如Factory Method等设计模式。

3)技术细节的隐藏。

当你写一个User或者SalesOrder类的时候,你希望专注于自己的业务逻辑,比如创建用户,删除用户,创建订单,删除订单这些具体的业务。如果你在这些类中再加上访问记录(log)处理,就会明显的影响你程序的可读性。因为本质上log处理和你的业务逻辑没有什么联系,两者混杂在一起就会让人看起来比较头大。还有一些异常处理类的逻辑也会产生同样的问题。你怎样才能把这些和真正的业务逻辑无关的逻辑分离出去?

问题的回答

Spring给出的解决方案是这样的。

1)对象的生命周期问题。=>DI

2)松耦合问题。 => DI

3)技术细节的隐藏。=>AOP

首先Spring是怎么实现DI的呢,是通过DI Container来实现的。

在没有使用DI的Web应用中,Controller用到Service的时候,会生成(new)一个,Service用到DAO的时候,也是同样的生成(new)一个。

no DI

而使用了DI的Spring,则将实例化的工作全部交给了DI Container去做。

Controller中仅仅声明了Service接口的一个属性,具体的实现(new)没有去做,同样Service中也只是声明了一个DAO接口的一个属性,也没有去实现(new)。当需要实例的时候,就让DI Container根据配置去找到合适的类去实例化相应的接口属性。

DI

而用Spring写成的Web程序,其处理顺序可以用下图来表示

Spring Flow

  1. Dispatcher Servlet接收用户访问请求
  2. Dispatcher Servlet利用HandlerMapping取得URL所对应的Controller对象
  3. Controller来实行业务逻辑,调用Service对象和DAO对象得到业务数据,并把数据放到Model中。并返回一个View的名字,希望把数据显示到该View上。
  4. Dispatcher Servlet得到View的名字后,调用View Resolver来得到相应的View对象。
  5. Dispatcher Servlet把View对象生成为一个画面(View),画面包含Model对象中的数据,然后把这个View返回给用户(response)。用户的浏览器把这个画面呈献给用户。

 …

我对Javascript中的闭包Closure的理解

怎样理解 Javascript Closure 也就是闭包的概念,想必很多人在为此头疼。

笔者先后参考了下面这些资料

MDN Javascript Closure https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

阮一峰的博客 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

Frank Fang的博客 http://www.cnblogs.com/frankfang/archive/2011/08/03/2125663.html

作者们都声称自己搞懂了闭包的概念,可自己还是看的云里雾里。

直到笔者看到下面这篇文章,才开始真正理解闭包的概念和应用场景。

Jonathan D. Johnson的博客 http://jondavidjohn.com/javascript-closure-explained-using-events/

下面我试着把这篇文章边翻译边把自己的理解写出来。

先看一下下面这段程序,

效果:在第3次按下button的时候显示”Third time’s the charm”的消息框。

在sap hybris的accelerator中添加hybris cms组件(hybris cms component)的方法

在hybris的accelerator中新建CMS组件(hybris cms component)的步骤包括:

*注意:hybris addon中的步骤有所不同,将在另一篇文章中记述。

  1. 自定义hybris item,在extension的items.xml文件中定义,类似于任何其他hybris item。
  2. 一个继承AbstractCMSComponentController的Spring MVC控制器,或使用DefaultCMSComponentController。
  3. 用于在页面上呈现组件的JSP,根据需要使用HTML,CSS和Tag Libraries。

可以通过XML配置为组件自定义hybris WCMS Cockpit:

  1. editorArea_typeName.xml:WCMS Cockpit编辑器区域的配置文件。
  2. contentEditor_typeName.xml:用于LiveEdit模式和联机编辑的配置文件
  3. wizardConfig_typeName.xml:如果通过向导对话框添加组件,则通过此文件进行向导配置。

在SAP hybris中实行单体测试(Unit Test)的注意事项

在SAP hybris的单体测试中,出现如下错误信息:

sap hybris在新建自定义cms component时的注意事项

在SAP hybris中添加自定义的CMS Component,需要注意以下几点:

参考链接: https://wiki.hybris.com/pages/viewpage.action?pageId=294094319

  1. 在addon中添加,可免去对accelerator的修改
  2. 在/<addon-name>/resources/<addon-name>/web/spring/<addon-name>-web-spring.xml中添加renderer和rendererMapping的定义
  3. 使用ant命令安装addon

<addon-name>-web-spring.xml的代码示例如下:

有了uwsgi为什么还需要nginx

在python的web开发中,我用flask框架写了一个小程序,部署的时候,我用到了uwsgi来做容器。

在学习uwsgi部署的过程中,另一个关键词nginx频繁的跳出来。这两者通常是成对出现的。

你有没有和我一样的困惑,为什么有了uwsgi我们还需要nginx?

我是说,既然uwsgi能够展现你想要的内容,那nginx存在的意义在哪里?

首先,nginx是一个HTTP 服务器。如果你是学Java出身的,说到HTTP服务器你应该会想到Apache。

类似的uwsgi可以比喻为tomcat。

nginx官方网站上给出的一张图片很好的揭示了nginx的角色。

architecture-nginx

我所理解的nginx的主要功能,有以下几个部分:

  • nginx处理静态内容请求更专业、快速
  • nginx可以缓存请求。如果让uwsgi来直接接受请求的话,uwsgi需要花费大量的时间来等待request,这本身对web应用所在的主机是很大的资源浪费。
  • 分发请求。假如你有好几个web应用,分布在不同的主机上,nginx可以把请求分发到各自的web应用来进行处理。这一特点是nginx可以用来做负载均衡器。
  • 相比web容器,nginx的漏洞更少更安全
  • nginx可以更好的处理HTTPS
  • nginx有网关(gateway)的作用,可以过滤访问IP。

 …

在Python中将datetime字符串转换为utc timestamp

在python中有很多方法将datetime的字符串转换为 utc timestamp

网上找了好多,看起来都纷繁复杂。本文就想简单的做好一件事,就是将datetime的字符串转换为utc timestamp。

理解这个转换的关键,在于理解python中所有的日期字符串都被python解读为local time。

也就是说,同样是’2015/10/27 00:00:00’这个字符串,虽然身处东京的我和身在伦敦的你看到的是同一个字符串,但他们本身被python解读为两个不同地方的日期和时间。

如果想让python不去理会时差,而只想要utc格式的时间戳的话,用calendar.timegm()函数即可实现。

现举例如下:

Windows下SQL Server2008的定时备份策略

在windows下对SQL Server2008数据库进行定时备份,需要做以下工作:

1.编写备份数据库的bat文件,内容形似:

backup database testdb to disk=’d:\backup\testdb.bak’  >> .\backup.log

2.编写copy数据库备份文件并重命名的bat文件,形似:

SET DT=%DATE:~0,4%%DATE:~5,2%%DATE:~8,2%

COPY D:\backup.bak  D:\backup%DT%.bak >> .\copy.log

2.建立两个windows计划任务,分别选定时间和周期执行上述备份bat文件。

这样就可以实现sql server的定时备份策略了。…

Cookie 无法保存的另一个可能原因

在项目中需要往cookie中写数据,之前遇到的问题是如果写入的内容超出了单个cookie的大小限制(4096字节,4KB),则服务器端的response就会异常。

今天的问题则是,虽然已经把很长的内容分割成立个好几段,并分别写入了不同的cookie中,但服务器端同样不能正常响应。

查资料得知,不知浏览器对同一个站点的cookie的个数,单个cookie文件的大小有限制,服务器还对每一次请求的httpheader的大小有限制。

对tomcat服务器来说,需要修改server.xml中的响应配置,在形如

[sourcecode language=”xml”]
<Connector port=”8080″ protocol=”HTTP/1.1″
connectionTimeout=”20000″
redirectPort=”8443″ maxHttpHeaderSize=”40960″/>

[/sourcecode]

的部分进行相应配置,上面的maxHttpHeaderSize就规定了本服务器可以处理的HttpHeader的大小上限为40KB。

 …