The First One:

(function($) {
	$.fn.joey = function(options) {
		debug(this);
 
		var opts = $.extend({}, $.fn.joey.defaults, options);
 
		return this.each(function() {
			$this = $(this);
 
			// build element specific options
			var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
 
			// do something
		});
	};
 
	// private function for debugging
	function debug($obj) {
		if (window.console && window.console.log)
			window.console.log('joey selection count: ' + $obj.size());
	}
	;
 
	// plugin defaults
	$.fn.joey.defaults = {
		// some options
	};
 
})(jQuery);

 

The Other One:

;(function($) {
	$.fn.theplugin = function(options) {
		debug(this);
 
		var opts = $.extend({}, $.fn.theplugin.defaults, options);
 
		if (this.length > 1) {
			this.each(function() {
				$(this).theplugin(options)
			});
			return this;
		}
 
		this.initialize = function() {
			$this = $(this);
 
			// build element specific options
			var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
 
			// do something
 
			return this;
		};
 
		// public function
		this.foo = function() {
			// do someting
		}
 
		// private fucntion
		function debug($obj) {
			if (window.console && window.console.log)
				window.console.log('theplugin selection count: ' + $obj.size());
		}
		;
 
		// plugin defaults
		$.fn.theplugin.defaults = {
			// options
		};
 
		return this.initialize();
	}
})(jQuery);

进入微博时代,我的惰性越发泛滥,别说不写博客,几乎瞄都没瞄上两眼。这次借着MACBOOK PRO的新鲜劲儿涂鸦两笔,假装是应@_dz_菠菜_的要求,其实是秀秀装逼感。

话说我上一个本子是T60 2007-FA6,港版的水货本,用到现在已经4岁了,跑起WIN7来跟个破车似地,尤其是动不动就会停顿住那么几十秒抗议我对它的摧残,即使我将内存奢侈地增加到了3G也于事无补。所以,我趁着有预算赶紧折腾着换个新本,基本上是在THINKPAD RW3和MBP MC721ZP之间选择,THINKPAD新款的T420那悲剧性的16:9屏幕和可耻的多点触控板让我毫无犹豫地把他放弃了,而MBP是多么的标致得适合装逼,虽然我加配后MBP要15400HKD,而水THINKPAD只要8200RMB,但是尼玛的MBP是行货,有木有!!!

取回本子后真的有些爱不释手,绝对标致,多点触控板更是大爱,基本上可以抛弃鼠标愉快地完成一切操作了,操作细节我就不说,嘿嘿。因此,我也就放弃了再配一个Magic Mouse的念想,完全没有必要,顶多继续偶尔用下我那个灵敏度欠奉,时不时还掉线的罗技M555b就行了。

开机初始化后自然是配置网络,配置VPN(我发誓我不经常翻墙的,体力不好),安装除IE外的各系浏览器,安装输入法——我选择的是FUN INPUT TOY。

然后一顿狂找各种软件,MAC APP STORE的收费软件比IOS的要贵不少,看着都肉疼(我为自己说出这话小小地内疚一下),所以我只购买了不超过3款的价格在5刀以下的软件,其它的都是免费的或者破解的(再鄙视一下自己)。

以下是软件列表,有比我更白痴的可以参考:

aMule:电驴,你懂的;

Brew:MAC的apt-get,免费;

FileZilla:FTP客户端,为什么选它,因为它免费;

uTorrent:BT客户端,还是免费;

Speed Download:下载工具,传说是MAC下最好的,我尝试使用免费的folx,但是是在太烂了,而SD太他妈贵了,所以我盗版了——我真的觉得下载工具应该免费的,:P。

iTerm:用以替换系统自带的终端,免费;

CleanMyMac:系统清理,用以清理垃圾,卸载软件不错,盗版的;

Disk Order:MAC下类似TC的工具,貌似盗版,但我好像不用KEY不用破解也能用;

gfxCardStatus:显示显卡状态,并能用以切换集县或独显,免费;

MiniUsage:在任务栏显示系统状况,信息很齐全并能显示占资源最多的十个进程,免费。之前装了个istat menu,搞得任务栏跟花一样,果断扔了;

istat pro:Dashboard中的系统状况查看插件,免费;

HyperDock:让Dock有WIN7一样的预览效果,可点击预览图激活或关闭窗口,我忘了是不是盗版了;

iBackup:系统备份工具,免费;

MyTunesControllerPlus:任务栏图标控制itunes,并能桌面显示歌词,免费;

ntfsMounter:MAC默认只读NTFS格式,其实内置可写的,此工具就是打开写功能,运行后任务栏有个很丑的图表,将NTFS分区挂上去就OK了,免费;

QuickSilver:神器,可以快速查找、启动、各种方式打开你需要的种种,功能和系统自带的Spotlight,Google Quick Search Box有些重叠,免费;

smcFanControl:显示温度和风扇转速,可指令在正常和高转速之间切换,免费;

The Unachiever:比自带的好用,免费;

DropBox:你懂的;

Balsamiq Mockups:原型绘制工具,我有KEY,不算盗版;

Evernote:笔记本,资料管理,免费;

FreeMind:思维导图工具,免费;

iChm:看名字就知道了,免费;

Stanza:看电子书的,免费;

Xee:图片浏览,免费;

MacVim:神器,免费;

Office 2011 for Mac:盗版,不需要注册也能用;

MPlayerX:播放器,免费;

射手播放器:买的,2.99刀;

QQ:不解释;

Twitter for Mac:不解释;

欧陆词典:带屏幕取词,免费;

RDC:远程连接WINDOWS桌面,免费;

Vmware Fusion:虚拟机软件,盗版的;

开发方面安装JAVA、RUBY都很简单,系统有自带的,ECLIPSE直接下载就能用,安装插件和windows一样,就是Subclipse默认只能用SVNKIT,JAVAHL需要安装SVN才有,下载个openCollabNet版安装就行;

MySQL直接到官网下载安装即可。

UML工具用惯了JUDE,现在改名叫Astah,还是用了这个,跨平台就是好,免费;

其实MAC的软件安装真的超简单,基本上拖拽到应用程序文件夹就成了,package就直接双击安装;

一不小心写了这么长,收工。

要实现修改历史记录的功能,以前我们可以使用Hibernate Interceptor,hibernate 3.0之后,可以使用Event Listener。

关于这个,已经有其他人阐述过了,请猛击这里:http://bit.ly/afOs8p

AJAX Upload

分类: 相对挨踢 | 标签: , | 没有评论

推荐一下这个AJAX Upload,基于JQuery,方便快捷,是居家旅行、杀人放火之利器。

用法:

new AjaxUpload('upload_button_id', {action: 'upload.php'});

前一参数是相应事件的页面元素ID,任何元素都可以,后一个参数是执行上传的URL。

new AjaxUpload('#upload_button_id', {
	// 执行上传文件的URL
	action: 'upload.php',
	// 对应传统的input file的名称
	name: 'userfile',
	// 其它要同时post的数据
	data: {
		example_key1 : 'example_value',
		example_key2 : 'example_value2'
	},
	// 选择文件后自动上传
	autoSubmit: true,
	// 文件被选择后触发
	// Useful when autoSubmit is disabled
	// You can return false to cancel upload
	// @param file basename of uploaded file
	// @param extension of that file
	onChange: function(file, extension){},
	// 文件被上传完成前触发
	// You can return false to cancel upload
	// @param file basename of uploaded file
	// @param extension of that file
	onSubmit: function(file, extension) {},
	// 文件上传完成后触发
	// @param file basename of uploaded file
	// @param response server response
	onComplete: function(file, response) {}
});

原理:

其实简单得要死,不过是偷偷的在背后生成一个iframe,构建一个表单,然后提交就是了。

基本上就这样了,细节自己去官网看吧。

一者好久没博了,所以写篇凑个数,二者顺便记录一下,催眠我自己的记忆。

AOP,用我们的普通话说就是面向方面变成,实际上是OOP编程的一个补充。说简单点就是实现横切(crosscutting)的工具,可使代码更加模块化,被横切的被称之为关注点。OOP的基本单元是Class,而AOP的基本单元是Aspect。日志、安全、事务等都是一些典型的横切。比如我们最近的一个项目,为了了解程序的性能,就使用了AOP记录一些服务方法的执行时间。

一、概念

1、连接点(join point):指程序执行过程中的一个特定点,比如方法调用、抛出异常、对象初始化等等,用来定义你的程序在什么地方加入新的逻辑。

2、通知(advice):特定的连接点出运行的代码称为通知。通知有很多种,比如前置通知、后置通知等。

3、切入点(point cut):指一个通知该何时执行的一组连接点,典型的切入点如对某个类所有方法调用的集合。

4、方面(aspect),通知和切入点的组合称为方面,也即定义了程序执行的逻辑以及何时应该被执行。

5、织入(weaving):方面被加入程序的过程,静态织入一般在编译时进行,而动态织入则在运行时进行,Spring AOP属于动态织入。

6、目标(target):也就是被aop的对象。

7、引入(introduce):就是向对象中加入新的属性或方法,比如可以修改它使之实现某个接口。

二、应用

1、使程序支持@Aspect

在spring配置文件中加入:

<aop:aspectj-autoproxy/>

2、定义一个方面
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
 
@Aspect
public class SimpleAspect {
 
}
3、声明一个切入点:
@Pointcut("execution(* transfer(..))") // the pointcut expression
private void anyOldTransfer() {} // the pointcut signature
4、Spring AOP支持的切入点表达式
  1. execution – 匹配方法执行连接点,也是使用Spring AOP最常用到的。
  2. within – 匹配特定类型,只是为了简化特定类型执行AOP的方法执行声明。
  3. this – 连接点必须是指定类型的实例。
  4. args – 连接点的参数必须是指定类型的实例。
  5. @target – 连接点执行对象类型必须有指定类型的注解(annotation)。
  6. @args – 连接点实参的运行时类型必须有指定类型的注解(annotation)。
  7. @within – 匹配具有指定注解(annotation)的类型
  8. @annotation – 连接点必须有指定的注解(annotaion)
5、组合连接点表达式
可以用&&, ||, !进行组合
6、声明通知(advice)
1)、前置通知(Before advice)

一个切面里使用 @Before 注解声明前置通知:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
 
@Aspect
public class BeforeExample {
 
	@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
	public void doAccessCheck() {
		// ...
	}
 
}
如果使用一个in-place 的切入点表达式,我们可以把上面的例子换个写法:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
 
@Aspect
public class BeforeExample {
 
	@Before("execution(* com.xyz.myapp.dao.*.*(..))")
	public void doAccessCheck() {
		// ...
	}
}
2)、返回后通知(After returning advice)

返回后通知通常在一个匹配的方法返回的时候执行。使用 @AfterReturning 注解来声明:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
 
@Aspect
public class AfterReturningExample {
 
	@AfterReturning("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
	public void doAccessCheck() {
		// ...
	}
}
说明:你可以在同一个切面里定义多个通知,或者其他成员。我们只是在展示如何定义一个简单的通知。这些例子主要的侧重点是正在讨论的问题。
有时候你需要在通知体内得到返回的值。你可以使用以 @AfterReturning 接口的形式来绑定返回值:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
 
@Aspect
public class AfterReturningExample {
 
	@AfterReturning(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()", returning="retVal")
	public void doAccessCheck(Object retVal) {
		// ...
	}
}
在 returning 属性中使用的名字必须对应于通知方法内的一个参数名。 当一个方法执行返回后,返回值作为相应的参数值传入通知方法。 一个 returning 子句也限制了只能匹配到返回指定类型值的方法。 (在本例子中,返回值是 Object 类,也就是说返回任意类型都会匹配)
3)、抛出后通知(After throwing advice)

抛出后通知在一个方法抛出异常后执行。使用 @AfterThrowing 注解来声明:
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
 
@Aspect
public class AfterThrowingExample {
 
	@AfterThrowing("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
	public void doRecoveryActions() {
		// ...
	}
 
}
你通常会想要限制通知只在某种特殊的异常被抛出的时候匹配,你还希望可以在通知体内得到被抛出的异常。 使用 throwing 属性不光可以限制匹配的异常类型(如果你不想限制,请使用 Throwable 作为异常类型),还可以将抛出的异常绑定到通知的一个参数上。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;
 
@Aspect
public class AfterThrowingExample {
 
	@AfterThrowing(pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()", throwing="ex")
	public void doRecoveryActions(DataAccessException ex) {
		// ...
	}
 
}
在 throwing 属性中使用的名字必须与通知方法内的一个参数对应。 当一个方法因抛出一个异常而中止后,这个异常将会作为那个对应的参数送至通知方法。 throwing 子句也限制了只能匹配到抛出指定异常类型的方法(上面的示例为 DataAccessException)。
4)、后通知(After (finally) advice)
不论一个方法是如何结束的,在它结束后(finally)后通知(After (finally) advice)都会运行。 使用 @After 注解来声明。这个通知必须做好处理正常返回和异常返回两种情况。通常用来释放资源。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
 
@Aspect
public class AfterFinallyExample {
 
	@After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")
	public void doReleaseLock() {
		// ...
	}
 
}
5)、环绕通知(Around Advice
最后一种通知是环绕通知。环绕通知在一个方法执行之前和之后执行。 它使得通知有机会既在一个方法执行之前又在执行之后运行。并且,它可以决定这个方法在什么时候执行,如何执行,甚至是否执行。 环绕通知经常在在某线程安全的环境下,你需要在一个方法执行之前和之后共享某种状态的时候使用。 请尽量使用最简单的满足你需求的通知。(比如如果前置通知(before advice)也可以适用的情况下不要使用环绕通知)。
环绕通知使用 @Around 注解来声明。通知的第一个参数必须是 ProceedingJoinPoint 类型。 在通知体内,调用 ProceedingJoinPoint 的 proceed() 方法将会导致潜在的连接点方法执行。 proceed 方法也可能会被调用并且传入一个 Object[] 对象-该数组将作为方法执行时候的参数。
当传入一个 Object[] 对象的时候,处理的方法与通过AspectJ编译器处理环绕通知略有不同。 对于使用传统AspectJ语言写的环绕通知来说,传入参数的数量必须和传递给环绕通知的参数数量匹配(不是后台的连接点接受的参数数量),并且特定顺序的传入参数代替了将要绑定给连接点的原始值(如果你看不懂不用担心)。 Spring采用的方法更加简单并且更好得和他的基于代理(proxy-based),只匹配执行的语法相适用。 如果你适用AspectJ的编译器和编织器来编译为Spring而写的@AspectJ切面和处理参数,你只需要了解这一区别即可。 有一种方法可以让你写出100%兼容Spring AOP和AspectJ的,我们将会在后续的通知参数(advice parameters)的章节中讨论它。
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.ProceedingJoinPoint;
 
@Aspect
public class AroundExample {
 
	@Around("com.xyz.myapp.SystemArchitecture.businessService()")
	public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
		// start stopwatch
		Object retVal = pjp.proceed();
		// stop stopwatch
		return retVal;
	}
 
}
方法的调用者得到的返回值就是环绕通知返回的值。 例如:一个简单的缓存切面,如果缓存中有值,就返回该值,否则调用proceed()方法。 请注意proceed可能在通知体内部被调用一次,许多次,或者根本不被调用。
7、通知参数(Advice parameters)
Spring 2.0 提供了完整的通知类型 – 这意味着你可以在通知签名中声明所需的参数,(就像在以前的例子中我们看到的返回值和抛出异常一样)而不总是使用Object[]。 我们将会看到如何在通知体内访问参数和其他上下文相关的值。首先让我们看以下如何编写普通的通知以找出正在被通知的方法。
1)、访问当前的连接点
任何通知方法可以将第一个参数定义为 org.aspectj.lang.JoinPoint 类型 (环绕通知需要定义为 ProceedingJoinPoint 类型的, 它是 JoinPoint 的一个子类。) JoinPoint 接口提供了一系列有用的方法, 比如 getArgs()(返回方法参数)、getThis()(返回代理对象)、getTarget()(返回目标)、getSignature()(返回正在被通知的方法相关信息)和 toString()(打印出正在被通知的方法的有用信息)。
2)、传递参数给通知(Advice)
我们已经看到了如何绑定返回值或者异常(使用后置通知(after returning)和异常后通知(after throwing advice)。 为了可以在通知(adivce)体内访问参数,你可以使用 args 来绑定。 如果在一个参数表达式中应该使用类型名字的地方使用一个参数名字,那么当通知执行的时候对应的参数值将会被传递进来。 可能给出一个例子会更好理解。假使你想要通知(advise)接受某个Account对象作为第一个参数的DAO操作的执行,你想要在通知体内也能访问到account对象,你可以写如下的代码:
@Before("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &amp;&amp; args(account,..)")
public void validateAccount(Account account) {
	// ...
}
切入点表达式的 args(account,..) 部分有两个目的: 首先它保证了只会匹配那些接受至少一个参数的方法的执行,而且传入的参数必须是 Account 类型的实例, 其次它使得可以在通知体内通过 account 参数来访问那个account参数。
另外一个办法是定义一个切入点,这个切入点在匹配某个连接点的时候“提供”了一个Account对象, 然后直接从通知中访问那个命名的切入点。你可以这样写:
@Pointcut("com.xyz.myapp.SystemArchitecture.dataAccessOperation() &amp;&amp; args(account,..)")
private void accountDataAccessOperation(Account account) {}
 
@Before("accountDataAccessOperation(account)")
public void validateAccount(Account account) {
  // ..
}
如果想要知道更详细的内容,请参阅 AspectJ 编程指南。
代理对象(this)、目标对象(target) 和注解(@within, @target, @annotation, @args)都可以用一种简单格式绑定。 以下的例子展示了如何使用 @Auditable 注解来匹配方法执行,并提取AuditCode。
首先是 @Auditable 注解的定义:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditable {
	AuditCode value();
}
然后是匹配 @Auditable 方法执行的通知:
@Before("com.xyz.lib.Pointcuts.anyPublicMethod() &amp;&amp;  @annotation(auditable)")
public void audit(Auditable auditable) {
	AuditCode code = auditable.value();
	// ...
}
3)、决定参数名
绑定在通知上的参数依赖切入点表达式的匹配名,并借此在(通知(advice)和切入点(pointcut))的方法签名中声明参数名。 参数名 无法 通过Java反射来获取,所以Spring AOP使用如下的策略来决定参数名字:
如果参数名字已经被用户明确指定,则使用指定的参数名: 通知(advice)和切入点(pointcut)注解有一个额外的”argNames”属性,该属性用来指定所注解的方法的参数名 – 这些参数名在运行时是 可以 访问的。例子如下:
@Before(value="com.xyz.lib.Pointcuts.anyPublicMethod() &amp;&amp; @annotation(auditable)", argNames="auditable")
public void audit(Auditable auditable) {
	AuditCode code = auditable.value();
	// ...
}
如果一个@AspectJ切面已经被AspectJ编译器(ajc)编译过了,那么就不需要再添加 argNames 参数了,因为编译器会自动完成这一工作。
使用 ‘argNames’ 属性有点不那么优雅,所以如果没有指定’argNames’ 属性, Spring AOP 会寻找类的debug信息,并且尝试从本地变量表(local variable table)中来决定参数名字。 只要编译的时候使用了debug信息(至少要使用 ‘-g:vars’ ),就可获得这些信息。 使用这个flag编译的结果是: (1)你的代码将能够更加容易的读懂(反向工程)
(2)生成的class文件会稍许大一些(不重要的)
(3)移除不被使用的本地变量的优化功能将会失效。 换句话说,你在使用这个flag的时候不会遇到任何困难。
如果不加上debug信息来编译的话,Spring AOP将会尝试推断参数的绑定。 (例如,要是只有一个变量被绑定到切入点表达式(pointcut expression)、通知方法(advice method)将会接受这个参数, 这是显而易见的)。 如果变量的绑定不明确,将会抛出一个 AmbiguousBindingException 异常。
如果以上所有策略都失败了,将会抛出一个 IllegalArgumentException 异常
8、常用切入点表达式

execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
除了返回类型模式(上面代码片断中的ret-type-pattern),名字模式和参数模式以外,所有的部分都是可选的。 返回类型模式决定了方法的返回类型必须依次匹配一个连接点。 你会使用的最频繁的返回类型模式是 *,它代表了匹配任意的返回类型。 一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。 你可以使用 * 通配符作为所有或者部分命名模式。 参数模式稍微有点复杂:() 匹配了一个不接受任何参数的方法, 而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。 模式 (*) 匹配了一个接受一个任何类型的参数的方法。 模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。
下面给出一些常见切入点表达式的例子。
任意公共方法的执行:
execution(public * *(..))
任何一个以“set”开始的方法的执行:
execution(* set*(..))
AccountService 接口的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
定义在service包里的任意方法的执行:
execution(* com.xyz.service.*.*(..))
定义在service包或者子包里的任意方法的执行:
execution(* com.xyz.service..*.*(..))
在service包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service.*)
在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :
within(com.xyz.service..*)
实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :
this(com.xyz.service.AccountService)
‘this’在binding form中用的更多:- 请常见以下讨论通知的章节中关于如何使得代理对象可以在通知体内访问到的部分。
实现了 AccountService 接口的目标对象的任意连接点(在Spring AOP中只是方法执行) :
target(com.xyz.service.AccountService)
任何一个只接受一个参数,且在运行时传入的参数实现了 Serializable 接口的连接点 (在Spring AOP中只是方法执行)
args(java.io.Serializable)
请注意在例子中给出的切入点不同于 execution(* *(java.io.Serializable)): args只有在动态运行时候传入参数是可序列化的(Serializable)才匹配,而execution 在传入参数的签名声明的类型实现了 Serializable 接口时候匹配。
有一个 @Transactional 注解的目标对象中的任意连接点(在Spring AOP中只是方法执行)
@target(org.springframework.transaction.annotation.Transactional)
任何一个目标对象声明的类型有一个 @Transactional 注解的连接点(在Spring AOP中只是方法执行)
@within(org.springframework.transaction.annotation.Transactional)
任何一个执行的方法有一个 @Transactional annotation的连接点(在Spring AOP中只是方法执行)
@annotation(org.springframework.transaction.annotation.Transactional)
任何一个接受一个参数,并且传入的参数在运行时的类型实现了 @Classified annotation的连接点(在Spring AOP中只是方法执行)
@args(com.xyz.security.Classified)
9、参考并抄袭自

http://static.springsource.org/spring/docs/2.5.x/reference/aop.html

http://hi.baidu.com/wangyongjin87/blog/item/c9cf2cec4e19de232df534cb.html

Page 1 of 1112345...10...Last »