参数说明:
-xmx1280m:设置jvm最大可用内存为1280m。最大可设为3550m。具体应用可适当调整。
-xms1280m:设置jvm初始内存为1280m。此值可以设置与-xmx相同,以避免每次垃圾回收完成后jvm重新分配内存。
-xmn480m:设置年轻代大小为480m。整个堆大小=年轻代大小 年老代大小 持久代大小。持久代一般固定大小为64m,所以增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,sun官方推荐配置为整个堆的3/8。
-xss256k:设置每个线程的堆栈大小。jdk5.0以后每个线程堆栈大小为1m,以前每个线程堆栈大小为256k。更具应用的线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
-xx:permsize=64m:指定 jvm 中 perm generation 的最小值。 这个参数需要看你的实际情况。可以通过jmap 命令看看到底需要多少。
-xx:maxpermsize=128m:指定 perm generation 的最大值
-xx: useconcmarksweepgc:设置并发收集器
-xx:parallelgcthreads=8:配置并行收集器的线程数,即:同时多少个线程一起进行垃圾回收。此值最好配置与处理器数目相等。
-xx:cmsfullgcsbeforecompaction=0:由于并发收集器不对内存空间进行压缩、整理,所以运行一段时间以后会产生“碎片”,使得运行效率降低。此值设置运行多少次gc以后对内存空间进行压缩、整理。
-xx: usecmscompactatfullcollection:打开对年老代的压缩。可能会影响性能,但是可以消除碎片。
-xx:survivorratio=8:每个survivor space 和 eden之间的比例。
-xx:maxtenuringthreshold=7:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概率。
-xx:gctimeratio=19:设置垃圾回收时间占程序运行时间的百分比,公式为1/(1 n)。
-xnoclassgc:禁用类垃圾回收,性能会有一定提高。
-xx: disableexplicitgc:当此参数打开时,在程序中调用system.gc()将会不起作用。默认是off。
-xx: useparnewgc:设置年轻代为并行收集。可与cms收集同时使用。
-xx:-cmsparallelremarkenabled:在使用 useparnewgc 的情况下 , 尽量减少 mark 的时间。
-xx:cmsinitiatingoccupancyfraction=70:指示在 old generation 在使用了 70% 的比例后 , 启动 concurrent collector。
-xx:softreflrupolicymspermb=0:每兆堆空闲空间中softreference的存活时间。
为了分析java应用的内存泄漏,使用thread dump往往解决不了问题。使用jstat【eg:-gcutil pid 1000 5】工具查看运行的java应用的heap size,perm size ,survivor ratio等,当时你无法知道是什么对象把堆填满了。
什么是 java heap dump
首先需要搞懂什么是java heap,java heap是分配给实例类和数组对象运行数据区,所有java线程在运行期间共享heap中的数据。java heap dump相当于java应用在运行的时候在某个时间点上打了个快照(snapshot)。
如果你不懂啥是snapshot,点击
触发 java heap dump
有以下方法出发heap dump
分析 java heap dump
1:使用ibm heapanalyzer
是一款免费的jvm内存堆的图形分析工具,它可以有效的列举堆的内存使用状况,帮助分析java内存泄漏的原因。
下载解压后有一个ha413.jar,执行: java -xmx512m -jar ha413.jar /home/longhao/heapdump.out
执行结果如图所示:
2:jhat
是用来分析java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言oql,分析相关的应用后,可以通过http://localhost:7000来访问分析结果。
示例: $java_home/bin/jhat -j-xmx512m /home/longhao/dump.out
3:eclipse memoryanalyzer
是一个快速并且功能强大的java heap分析器,能够帮助你查找内存泄漏和减少内存消耗。在file>acquire heap dump>configure>hprof jmap dump provider设置一下分析应用的jdk,点击相关应用列表来生成heap dump并分析。
在socket,nio中的有些api中,申请的内存是直接向os要的,在堆中分析内存是查看不到的,可以通过-xx:maxdirectmemorysize=
在linux下进行java开发需要配置环境变量,下面介绍了三种配置环境变量的方法。
1.修改/etc/profile文件
如果你的计算机仅仅作为开发使用时推荐使用这种方法,因为所有用户的shell都有权使用这些环境变量,可能会给系统带来安全性问题。
(1)用文本编辑器打开/etc/profile
(2)在profile文件末尾加入:
java_home=/usr/share/jdk1.5.0_05
path=$java_home/bin:$path
classpath=.:$java_home/lib/dt.jar:$java_home/lib/tools.jar
export java_home
export path
export classpath
(3)重新登录
注解:
a. 你要将 /usr/share/jdk1.5.0_05jdk 改为你的jdk安装目录
b. linux下用冒号“:”来分隔路径
c. $path / $classpath / $java_home 是用来引用原来的环境变量的值,在设置环境变量时特别要注意不能把原来的值给覆盖掉了,这是一种常见的错误。
d. classpath中当前目录“.”不能丢,把当前目录丢掉也是常见的错误。
e. export是把这三个变量导出为全局变量。
f. 大小写必须严格区分。
2. 修改.bashrc文件
这种方法更为安全,它可以把使用这些环境变量的权限控制到用户级别,如果你需要给某个用户权限使用这些环境变量,你只需要修改其个人用户主目录下的.bashrc文件就可以了。
(1)用文本编辑器打开用户目录下的.bashrc文件
(2)在.bashrc文件末尾加入:
set java_home=/usr/share/jdk1.5.0_05
export java_home
set path=$java_home/bin:$path
export path
set classpath=.:$java_home/lib/dt.jar:$java_home/lib/tools.jar
export classpath
(3)重新登录
3. 直接在shell下设置变量
不赞成使用这种方法,因为换个shell,你的设置就无效了,因此这种方法仅仅是临时使用,以后要使用的时候又要重新设置,比较麻烦。
只需在shell终端执行下列命令:
export java_home=/usr/share/jdk1.5.0_05
export path=$java_home/bin:$path
export classpath=.:$java_home/lib/dt.jar:$java_home/lib/tools.jar
import java.util.calendar;
import java.util.gregoriancalendar;
public class caltest {
public static void main(string[] argv) {
caltest caltest = new caltest();
caltest.cal(2009, 11);
}
public void cal(final int year, final int month) {
calendar calendar = new gregoriancalendar();
calendar.set(year, month-1, 1);
int week = calendar.get(gregoriancalendar.day_of_week) - 1;
int days = calendar.getactualmaximum(gregoriancalendar.day_of_month);
system.out.println();
system.out.println("日\t一\t二\t三\t四\t五\t六");
for(int i = 0; i < week; i ) {
system.out.println("\t");
}
for(int i = 1; i <= days; i ) {
system.out.print(i "\t");
if((week i)%7 == 0) {
system.out.println();
}
}
}
}
运行效果:
有许多标准和实践准则可适用于java开发者,但此处要说的,是每个java开发者需坚守的基本原则。
一、为代码加注释。虽然每个人都知道这点,但有时却不自觉忘了履行,今天你“忘了”加注释了吗?虽然注释对程序的功能没什么“贡献”,但过一段时间,比如说两星期之后或者更长,回过头来看看自己的代码,说不定已经记不住它是干什么的了。如果这些代码是你个人的,那还算是走运了,不幸的是,当然了,大多数时候都是别人的不幸,很多时候大家都是在为公司写代码,写代码的人也许早已经离开了公司,但别忘了一句古话,有来有往嘛,为他人,也为我们自己,请为你的代码加上注释。
二、不要让事情复杂化。程序员有时候总是对简单问题想出复杂的凯发天生赢家一触即发官网的解决方案,比如说,在只有五个用户的程序中引入ejb、对程序实现了并不需要的框架(framework),之类的还有属性文件、面向对象凯发天生赢家一触即发官网的解决方案、多线程等等。为什么要这样做呢?也许我们并不知道是否这样会更好,但这样做也许可以学到一些新东西,或者让自己更感兴趣一些。如果是不知道为什么这样做,建议多请教经验丰富的程序员,如果是为了个人的目的,麻烦让自己更专业一点。
三、始终牢记——“少即是好(less is more)并不总是对的”。代码效率虽然很重要,但在许多凯发天生赢家一触即发官网的解决方案中,编写更少的代码并不能改善这些代码的效率,请看下面这个简单的例子:
if(newstatuscode.equals("sd") && (selloffdate == null || todaydate.compareto(selloffdate)<0 || (lastuseddate != null && todaydate.compareto(lastuseddate)>0)) || (newstatuscode.equals("obs") && (obsdate == null || todaydate.compareto(obsdate)<0))){ newstatuscode = "nyp"; }
能看明白if条件语句是干什么的吗?能想出来是谁写的这段代码吗?如果把它分成两段独立的if语句,是不是更容易理解呢,下面是修改后的代码:
if(newstatuscode.equals("sd") && (selloffdate == null || todaydate.compareto(selloffdate)<0 || (lastuseddate != null && todaydate.compareto(lastuseddate)>0))){ newstatuscode = "nyp"; }else if(newstatuscode.equals("obs") && (obsdate == null || todaydate.compareto(obsdate)<0)) { newstatuscode = "nyp"; }
是不是读起来容易多了呢,在此只是多加了一个if和两个花括号,但代码的可读性与可理解性就一下子提高了一大截。
四、请不要硬编码。开发者经常有意“忘记”或忽略掉这点,因为有些时候开发日程逼得实在太紧。其实,多写一行定义静态变量的代码能花多少时间呢?
public class a { public static final string s_constant_abc = "abc"; public boolean methoda(string sparam1){ if (a.s_constant_abc.equalsignorecase(sparam1)){ return true; } return false; } }
现在,每次需要将“abc”与其他变量进行比较时,不必记住实际代码,直接引用a.s_constant_abc就行了,而且在今后需要进行修改时,也可在一处修改,不会翻遍整个源代码逐个修改了。
五、不要“创造”自己的框架(framework)。确切来说,有数以千计的各种框架存在,而且大多数是开源的,这些框架都是优秀的凯发天生赢家一触即发官网的解决方案,可用于日常程序开发中,我们只需使用这些框架的最新版本就行了,至少表面上要跟上形势吧。被大家广为接受的最为明显的一个例子就是struts了,这个开源web框架非常适合用在基于web的应用程序中。是不是想开发出自己的struts呢,还是省点力气吧,回头看看第二条——不要让事情复杂化。另外,如果正在开发的程序只有3个窗口,就不要使用struts了,对这种程序来说,不需要那么多的“控制”。
六、不要使用println及字符串连接。通常为了调试方便,开发者喜欢在可能的所有地方都加上system.out.println,也许还会提醒自己回过头来再来删除,但有些时候,经常会忘了删除或者不愿意删除它们。既然使用system.out.println是为了测试,那么测试完之后,为什么还要留着它们呢,因为在删除时,很可能会删除掉真正有用的代码,所以不能低估system.out.println危害啊,请看下面的代码:
public class badcode { public static void calculationwithprint(){ double somevalue = 0d; for (int i = 0; i < 10000; i) { system.out.println(somevalue = somevalue i); } } public static void calculationwithoutprint(){ double somevalue = 0d; for (int i = 0; i < 10000; i) { somevalue = somevalue i; } } public static void main(string [] n) { badcode.calculationwithprint(); badcode.calculationwithoutprint(); } }
从测试中可以发现,方法calculationwithoutprint()执行用了0.001204秒,作为对比,方法calculationwithprint()执行可是用了10.52秒。
要避免浪费cpu时间,最好的方法是引入像如下的包装方法:
public class badcode { public static final int debug_mode = 1; public static final int production_mode = 2; public static void calculationwithprint(int logmode){ double somevalue = 0d; for (int i = 0; i < 10000; i) { somevalue = somevalue i; myprintmethod(logmode, somevalue); } } public static void myprintmethod(int logmode, double value) { if (logmode > badcode.debug_mode) { return; } system.out.println(value); } public static void main(string [] n) { badcode.calculationwithprint(badcode.production_mode); } }
另外,字符串连接也是浪费cpu时间的一个大头,请看下面的示例代码:
public static void concatenatestrings(string startingstring) { for (int i = 0; i < 20; i) { startingstring = startingstring startingstring; } } public static void concatenatestringsusingstringbuffer(string startingstring) { stringbuffer sb = new stringbuffer(); sb.append(startingstring); for (int i = 0; i < 20; i) { sb.append(sb.tostring()); } }
在测试中可发现,使用stringbuffer的方法只用了0.01秒执行完毕,而使用连接的方法则用了0.08秒,选择显而易见了。
七、多关注gui(用户界面)。再三强调,gui对商业客户来说,与程序的功能及效率同等重要,gui是一个成功程序的最基本部分,而很多it经理往往都没注意到gui的重要性。在现实生活中,许多公司可能为了节省开支,没有雇用那些有着设计“用户友好”界面丰富经验的网页设计者,此时java开发者只能依赖他们自身的html基本功及在此领域有限的知识,结果,很多开发出来的程序都是“计算机友好”甚于“用户友好”。很少有开发者同时精通软件开发及gui设计,如果你在公司“不幸”被分配负责程序界面,就应该遵守下面三条原则:
1、 不要再发明一次轮子,即不做无用功。现有的程序可能会有类似的界面需求。
2、 先创建一个原型。这是非常重要一步,用户一般想看到他们将使用的东西,而且可以先利用这个原型征求用户的意见,再慢慢修改成用户想要的样子。
3、 学会换位思考。换句话来说,就是从用户的角度来审查程序的需求。举例来讲,一个汇总的窗口可以跨页或者不跨页,作为一个软件开发者,可能会倾向于不跨页,因为这样简单一些。但是,从用户的角度来看,可能不希望看到上百行数据都挤在同一页上。
八、文档需求不放松。每个商业需求都必须记录在案,这可能听上去像童话,似乎在现实生活中很难实现。而我们要做的是,不管开发时间多紧迫,不管最终期限多临近,对每个商业需求都必须记录在案。
九、单元测试、单元测试、单元测试。关于什么是单元测试的最好方法,在此不便细说,只是强调,单元测试一定要完成,这也是编程中最基本的原则。当然了,如果有人帮你做单元测试自然是最好,如果没有,就自己来做吧,当创建一个单元测试计划时,请遵守以下三条最基本的原则:
1、 先于编写类代码之前编写单元测试。
2、 记录单元测试中的代码注释。
3、 测试所有执行关键功能的公有方法,这里不是指set和get方法,除非它们是以自己独特方式执行set和get方法。
十、质量,而不是数量。有些时候因为产品问题、期限紧迫、或一些预料之外的事情,导致常常不能按时下班,但一般而言,公司不会因为雇员经常加班而对之表扬和奖励,公司只看重高质量的工作。如果遵守了前九条原则,你会发现自己写出的代码bug少且可维护性高,无形中质量提高了一大步。
第二:不要把“好像”;“有人会……”;“大概”;“晚些时候”;“或者”;“说不定”之类放在嘴边。尤其是和上级谈论工作的时候。
我十分痛恨听到的一句话是:“我晚些时候会把这个文件发给所有的人”;因为这往往预示着我必须时刻提醒他不要忘记。同样,以下这些言辞也会让人觉得厌恶至极:
“到时候有人会把那些东西都准备好”
“大概是明天”
“明天或者后天客户会过来拜访”
“好像他说……”
一般是人都会这样说话的,因为这样第一给自己留下了广阔的余地,第二也不会给别人造成很大的压迫感,好像什么事情一定要弄个水落石出似的。说实话大学里面再用功的人都有一半是混的。一个人要么是在课堂上是混的,要么下课之后是混的。两个都没有带有混的色彩的人,要么是超级牛人,要么是神经病。所以,就因为人人都在混的,所以校园是一个浪漫的地方,校园也容易让人单纯。所以学生社团的工作往往是效率很低的,我现在回想起学校里做的工作,当时还觉得挺卖力的,但工作了之后才开始感觉到什么是效率。当你进入了用金钱计算时间的地方之后,你要尽可能的避免在学校里养成的这种习惯。如果上级问你什么时候能实施你给他的承诺,而你回答“今晚或者明天早上”这样的答案对于他来说完全等同于你没有回答,并且还给他留下了一个坏印象。(当然,这样的回答往往在学校社团,学生会工作中是常见的)
有一个寓言故事,一只小老鼠刚刚出世不久,老鼠妈妈问小老鼠:你现在能看见了吗? 小老鼠说:能。 老鼠妈妈说:那你能看到那块红薯吗? 小老鼠说:是的。老鼠妈妈说:那是一块石头,这说明你不但还看不见东西,你连嗅觉都还没有。
似是而非的应答往往一样会暴露出你更多的弱点。可能是以下中的一个或几个:
1.你之前没有想到这个工作,或者一直在拖延。
2.你没有责任心,认为这些并不重要。
3.你应付上级。
4.你不敢说真话。
5.你喜欢逞能,答应一些做不到的事情。
6.你不能独立工作。
当你的上级在以上选项中怀疑的时候,潜意识中你已经同时具备了以上所有的弱点了。
相反的看来,这样的回答,总是让上司恼火。
第一,他的问题没有得到回答,只是起到了提醒你的作用。
第二,他依然需要记住提醒你,因为他不知道你是否真正已经落实了工作。
第三,他不知道有多少你已经做了的事情中,都是这样没有落实的。(这点非常致命)
第四,往往因为没有得到满意的答案,上司自己的计划不得不被耽搁或推迟或不能给出明朗的结束时间。
所以---------
甲问:你什么时候能把要这个漏洞修好?
乙说:我已经通知他们了,他们大概明天就会来修的。
一天后
甲问:维修公司什么时候回来,你找的是哪家维修公司?
乙说:好像他们说安排不出人来,如果可以的话,今天晚上或者明天下午就能过来。
一天后
甲问:漏洞怎么还没有修好?
乙说:我晚点再问问他们。
甲说:今天下午之前不解决,明天不用来上班了。
第三:不要拖延工作
很多人喜欢在学习和玩耍之间先选择后者,然后在最后时间一次性赶工把考试要复习的东西突击完成。但是在工作中请不要养成这样的习惯,因为工作是永远做不完的,容不得你“突击”。又或者,当你在徘徊和彷徨如何实施的时候,你的领导已经看不下去,自己去做了。----这是一个危险的信号。
往往我们总是想把事情从头到尾全部想好了,才开始走第一步-----就摔倒了。
举个例子: 我小学的时候第一次给我一个喜欢的女孩子打电话的时候,想象了各种情况-------1,她接电话的时候在做作业。2,她在做作业,她妈妈接的电话。3.她也很无聊,很想找人说话。4.她正在被父母训斥。 5.她正在想另外一个男孩。6.她父亲接电话。 7.她家正好来了什么亲戚,亲戚接了电话。 8.她接了电话,但父母就在身边,说话不方便。。。。。等等等等。我整整想了一个下午,想好了各种情况的心理准备和应对的策略。然后勇敢的拿起电话机,按下了那几个按钮。结果-------她不在家。
所以,当你徘徊不前而手足无措的时候,你要意识到你正在拖延工作。徘徊是因为害怕这个事情可能发生的后果需要自己承担或应付。工作的时候需要一种起码的自信,相信自己有能力,不管下一步是什么状况,我都能把它引导到我需要的那条线上去的。另外,告诉自己,不要想太多时间,如果不知道,就赶快求助,或想办法,苦恼和忧虑会给你更多的压力也会把剩下的时间蚕食殆尽。
另外,警告一下:永远不要想,我知道了,先把上级派的事情放一下,等这集《越狱》看完再说。----90%的情况下,你会忘记,或者来不及,因为这件事需要比你原先想象要更多的时间。说做就做,一直是很好的习惯。
第四:不要认为理论上可以实施就大功告成了!
这点太重要了,往往当真正实施的人开始做了才会发现计划完全等于鬼话。如果不亲自实践,做计划的人会早晚被实施的鄙视。永远需要提升自己的办实事的能力,而不是空谈。
首先,如果你是做办公室工作的,或者做策划和计划的。请千万不要把你自己都认为不太可能或者很难做到的事情,让别人试试看。比如,用一个下午的时间在人流量很少的地方举办露天歌唱会。这会让执行的人觉得你在玩他,拿他做实验。没错,理论上,在任何地方都能举办歌唱会,但是,在不同的地方,执行的人的心情是不一样的。
其次,和执行的人讨论你的安排。比如,新来的你的下属,你可以安排她坐在任何地方,但是如果那是一个很难和大家接触的角落,这可能比你什么都不安排更差。的确,理论上一个人要坐下来,需要的只是空间。但事实上远远不止那些。
再次,不要奢望一切会随着你的计划进行。理论上这个会议会持续两个小时,但是,这是“不考虑在开场后的30分钟全场都在调试话筒”,或者“场下没有提出如此尖锐的问题”的前提下的状态。 大学生已经习惯了把事情做到 "理论上看上去很美"的程度了。 论文,ppt讲演,考试,辩论赛…… 这些校园智商大比拼,都是教我们如何完美的做好“纸上谈兵”的功夫。 你一定要相信自己能“搞定”事情的能力比想象的弱。
如果你是在学校的学生,测试一下自己,能否能搞定以下这些状况:
1.学校要制作一套校服,由你去寻找供应商,砍价,至少有三家公司的报价。
2.学校保安抓住一个学生偷窃,怎么处理?
3.学校的一个很重要路段的路灯坏了,你能否让它三天内继续亮起来。
4.食堂需要请一位专门烧清真菜的厨师,一周内到岗位。
当你开始思考以上这样的问题的时候,你会发现,他的思路和“看过去两年这个公司的业绩趋向,做出一个下个季度的市场策划方案”要相差极大。你会发现后者只要你做到“看上去很完美”,没有人知道按照你这样做结果会怎样。而上述的工作你只要一想,就会体会到不少的压力。因为你不处理好,结果就是明显的失败更大的问题就会相继发生。
对了,这种感觉就是“工作”给你的感觉!这就是“工作”和“纸上谈兵”的差别!
第五:不要让别人等你
在任何情况下都不要让别人放下手头的工作来等你。在大学中可能只是同寝室的人的几句半开玩笑的抱怨,在工作上很可能导致你的潜在凯发k8网页登录的合作伙伴的丢失。
你在做一个工作的同时要知道别人的进度,而永远不要落后。
这不像是在考试,你比别人做的慢,别人可以先交卷,你到时间了做不完你自己承受扣分。在工作中的情况是这样的:这是一场没有人能做完的考试,所有的人,都分配做一张试卷的不同部分,有的人分到的是阅读理解,有的人做的是完形填空,有的人做的是语法…… 然后大家做完了相互抄,这样,所有人都做完了。 如果大家都把各自的部分做完了,而你却还在没有做完,那么做得快的别人会开始做你的那部分题目,然后也是相互抄。慢慢地,大家会发现你的工作量完全可以由另外人来代替,整个团队中可以不需要你,这个时候,没有人从你这里得到试卷的答案,也没有人会给你他们的答案--------很不幸,你已经没有利用价值了。
请一定记住这个例子。
第六:不要认为细节不重要
在大学里,往往做事粗枝大叶,看看差不多就行了。相反,在企业里管理的精髓就在于将简单的事情做到细节。一个慌忙寻找保险箱钥匙的动作就很有可能丧失你晋升财务主管的机会。
公司的管理,其实需要的并不是把很难的事情做到90%----比如,优化管理层的核心工作流程、改变公司在当地政府面前的形象,提高产品质量,改善工作环境…… 而管理要做的是把每个简单的事情做到100%-----比如,把公司的每个人的档案都按照一定的规律整齐的存放起来、在门卫设立一个外来人员的签到台、把会议室多余的椅子拿走、和电视台讲好下个礼拜三来公司做采访、把试用装送到客户手里、在生产的咖啡上加一个口子、给下一期的封面人物拍照……等等如此。 如果你能把所有细节的问题都如实做到,那你才有开口升职的本钱。
很多人在毕业的时候不知道自己将来要做什么,于是就和自己说:我以后做管理吧!做管理?问一下自己,如果,公司资产被偷窃了,所有员工士气低下,办公室杂乱无章,公司电梯又坏了,打印机没墨了,采购计划超支了,产品滞销了,客户迟到了……你愿意解决这样的问题,并从小事开始做起吗?想好了这些再考虑是否把管理看得太空洞了。
第七:不要表现得消极,仅仅因为你所做的事情不是你的兴趣所在。
很显然,在学生时代,当做到自己喜欢的时候,我们会pay200%的精力去创造,但如果是枯燥的事务,我们便懒得理睬,最好能有办法应付过去。但在工作上80%你所做的事情都是繁琐而看似机械的,如果仅仅为此而表现的闷闷不乐,那么你会郁闷更久。要知道你的上司已经为这个项目够烦恼了,你还想让他看到你的表情吗?
学会喜欢自己的工作,并把注意力放在日常工作能学到些什么上去。如果现在你努力的抱怨工作,那么接下来你就是努力的寻找工作。尽量少用“有趣”,“好奇”之类的词语来描述自己想要的工作,而是“充实”,“有成就感”,“乐意”
之类。
想想以下职位,你会发现生活中很多工作不是在等你有很好的状态下让你做的很有趣的事情:
1.高速公路收费口的收费员:一天都是面对一个小窗口,把一张卡片送出去,这样要持续好几年。
2.学校食堂厨师:永远在烧大排和鸡腿。烧一年。
3.作家:交稿期要到了,我还在孕育灵感,两个星期没吃早饭了。
4.外科医生:刚刚睡着,马上叫我做一个3小时的手术。这样至少一周一次。
5.门市部销售:产品不好卖,8点上班来就坐在店门口,一个人,坐到晚上6点,今天没有一个人来,和昨天一样。
6.公交司机:我开车不用你指挥。这条线路我开了三年了。
7.宠物商店店员:生意不好,还要一早就过来听着20条狗的叫声一整天,听一年。
8.公司职员:晚上两点下班,第二天还要8点上班。关键是路上还要一小时。这样已经一个月了。
再想想自己是不是只是接触了这个工作一个月或者才碰到没几个困难,这个时候抱怨的声音最大。
千万不要想着去选择一个有趣的职业,因为没有那样的工作存在。没有哪一“种”行业是开心的,因为如果有,那所有人都去干那个了。最多试着问问自己本身的兴趣吧。self exploration。
第八:绝对不要把改善工作能力仅寄托在公司培训上
人绝对不可能经过一次培训就脱胎换骨。相反,集体培训上学到的东西往往是最用不上的信息。 就像食堂烧大锅菜一样,总没有你最想吃的菜,因为这样做容易,并且不容易得罪人。
很多学生很看重所选的公司有没有培训,这说明,你不但不知道这个公司做什么,你甚至不知道怎样学习这些技能。
我的感悟是如果你不知道怎么学你想要的知识,也不知道你想要的知识是什么,你只会做出两种行为:1。等待别人来教你,并且等待别人发现你不知道的地方。2.寻找现成的答案并且拷贝。期待公司培训的人,就很大概率上是第一种人(不排除极少真正优秀的公司培训)
许多的同学有这样的习惯思维:
因为,这个公司的培训能结束达到多少多少的程度
又因为,这个程度正好是我想达到的
所以我尽力进这家公司
因为我进了这家公司
所以它自然会使我达到了这个期望的程度。
我们把参加培训和达到效果很幼稚的画上了等号。其实往往集体培训上所得到的信息是最没有实际操作价值的。永远不要期望单靠听课,靠老师把同样的东西给所有的人,你会得到比别人更多。把更多的心思放在观察和思考自己的需要上,找到问题的所在再通过观察和实践得到的答案才是真正的知识。
所以,刚刚开始工作,什么都不会,不要认为那样是正常的,因为公司还没有培训过呢!等我接受培训了之后,我就全都会了。如果你一无所知还等待别人会可怜你的无知而施舍你知识,那你会为你的无知而付出更多的智商。
第九:不要推卸责任
推卸责任是害怕的条件反射。不要认为别人看不出这点。
我记得我小学里的一件事情。我一次作业没有带来,老师要训斥我,说:你怎么老是作业不带?
我当时说:不是。。。。 当我正要支支吾吾时候,老师说:什么不是?你带来了没有?
我说:没有
老师说:那不就是没有带!什么不是!就是!
之后我就发现,我只是害怕承担责任而条件反射似的就说了“不是”,仔细观察一下周围,你会发现,身边有无数的人在用“不是”作为被责问之后的第一反应。
其实现在很多人面对工作也是这样,当上级责问的时候,很条件反射的就做出了推卸动作,然而这样的动作,接下来往往是无力的辩解,以及一些很粗糙的借口。这样会让上司感到你这个人很难沟通,并且很不真实。
另外一种情况,就是无论什么情况下,我指责一个人,他永远是强调客观。其实这点才是学生最典型的特征。这说明他太容易受到其他事物的影响,并受它们决定。如果你和上司之间会出现以下类型的对话,想想是不是需要改一下你的处事方法。
甲:为什么到现在还没有给副总看你的报告!
乙:刚才c在打印,我在等他结束,现在他大概好了吧,我去看看
乙:还有点东西要修改
乙:b也要把东西给副总,我因为等他
乙:a他说我报告不用给副总看(a是乙的同级同事)
乙:不知道副总在不在哦,他的门关着。
乙:d他叫我帮他打印文件!怪他!(d是乙的同级同事)
乙:我的杯子突然找不到了,在找杯子。
不愿意负责任的人的不利在于他会让上司怀疑他的忠诚程度,因为上司给他的命令往往会因为一个小事情而被搁置或者打折执行,转而被他人的意识所改变。
第十:不要对自己说“我是大学生”
这点包涵了很多信息。
1.不要认为自己有多清高
2.不要仍然以学生的标准要求自己
3.不要感觉低人一等
4.不要等待别人的关怀
5.不要把这个作为犯错误自我安慰的借口
6.不要忘记搞清楚,公司究竟给自己的待遇是多少,老练些,这不是在做志愿者。
品格是处理好人际关系的基础,也是确保人际关系质量的关键。除此之外,人际交往的技巧也是尤为重要的。有些人做好事会让人感激一辈子,而有些人帮了别人却可能费力不讨好,不但得不到感激和回报,还让人心存嫉恨。将同样的产品以相同的价格推销给同一个客户,有些业务员可能被粗暴地赶出门,有些业务员却可能签到大单,甚至被客户奉为上宾。
人际交往的技巧是一个非常庞杂的话题,囿于篇幅,在这里只能结合我的切身体会做一些简单的列举,挂一漏万在所难免了。
1. 多给别人鼓励和表扬,尽量避免批评、指责和抱怨,不要逼别人认错。
2. 要学会倾听。不要说得太多,想办法让别人多说。
3. 如果你要加入别人的交谈,先要弄清楚别人究竟在说什么。
4. 交谈之前尽量保持中立、客观。表明自己的倾向之前先要弄清楚对方真实的倾向。
5. 注意对方的社交习惯并适当加以模仿。
6. 不要轻易打断、纠正、补充别人的谈话。
7. 别人有困难时,主动帮助,多多鼓励。
8. 不要因为对方是亲朋好友而不注意礼节。
9. 尽可能谈论别人想要的,教他怎样去得到他想要的。
10. 始终以微笑待人。
11. 做一个有幽默感的人。但是在讲笑话的时候千万不要只顾着自己笑。
12. 做一个脱离低级趣味的人。
13. 跟别人说话的时候尽量看着对方的眼睛,不管你是在说还是在听。
14. 转移话题要尽量不着痕迹。
15. 要学会聆听对方的弦外之音。也要学会通过弦外之音来委婉地表达自己的意思。
16. 拜访别人一定要事先通知。
17. 不要在别人可能忙于工作或者休息的时候打电话过去。除非是非常紧急的事情。
18. 给别人打电话的时候,先问对方是否方便通话。
19. 一件事情让两个人知道就不再是秘密。
20. 你在背后说任何人的坏话都迟早有一天传入这个人的耳朵。
21. 不要说尖酸刻薄的话。
22. 牢记他人的名字。养成偶尔翻看名片簿、电话本的习惯。
23. 尝试着跟你讨厌的人交往。
24. 一定要尊重对方的隐私,不管是朋友还是夫妻。
25. 很多人在一起的时候,当你与其中某个人交谈,请不要无视其他人的存在。
26. 要勇于认错。
27. 以谦卑的姿态面对身边的每一个人。
28. 给予他人同情和谅解。
29. 尽可能用“建议”取代“命令”。
30. 不要轻易做出承诺。承诺的事情就一定要尽可能做到。
二, 三, 四, 五, 六, 七, 八, 九, 十, 十一, 十二, 十三, 十四, 十五, |
|
this issue was discussed at the glassfish , see the discussion and the corresponding .
the good news is that quickly found out what the problem was and after the code went thru reviews, it was checked in and the fix went into yesterday's build.
here is how i created and deployed a grails application on glassfish v3:
export path=$grails_home/bin:$path
export grails_home=/tools/grails
create a simple grails app
vivekmz@boson(555)> grails create-app myfirstgrailsapp
welcome to grails 1.0.1 - http://grails.org/
licensed under apache standard license 2.0
grails home is set to: /tools/grails
base directory: /ws/sb
environment set to development
note: no plugin scripts found
running script /tools/grails/scripts/createapp.groovy
[mkdir] created dir: /ws/sb/myfirstgrailsapp/src
[mkdir] created dir: /ws/sb/myfirstgrailsapp/src/java
[mkdir] created dir: /ws/sb/myfirstgrailsapp/src/groovy
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/controllers
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/services
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/domain
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/taglib
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/utils
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/views
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/views/layouts
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/i18n
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/conf
[mkdir] created dir: /ws/sb/myfirstgrailsapp/test
[mkdir] created dir: /ws/sb/myfirstgrailsapp/test/unit
[mkdir] created dir: /ws/sb/myfirstgrailsapp/test/integration
[mkdir] created dir: /ws/sb/myfirstgrailsapp/scripts
[mkdir] created dir: /ws/sb/myfirstgrailsapp/web-app
[mkdir] created dir: /ws/sb/myfirstgrailsapp/web-app/js
[mkdir] created dir: /ws/sb/myfirstgrailsapp/web-app/css
[mkdir] created dir: /ws/sb/myfirstgrailsapp/web-app/images
[mkdir] created dir: /ws/sb/myfirstgrailsapp/web-app/meta-inf
[mkdir] created dir: /ws/sb/myfirstgrailsapp/lib
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/conf/spring
[mkdir] created dir: /ws/sb/myfirstgrailsapp/grails-app/conf/hibernate
[propertyfile] creating new property file:
/ws/sb/myfirstgrailsapp/application.properties
[copy] copying 2 files to /ws/sb/myfirstgrailsapp
[copy] copying 2 files to /ws/sb/myfirstgrailsapp/web-app/web-inf
[copy] copying 5 files to /ws/sb/myfirstgrailsapp/web-app/web-inf/tld
[copy] copying 87 files to /ws/sb/myfirstgrailsapp/web-app
[copy] copying 17 files to /ws/sb/myfirstgrailsapp/grails-app
[copy] copying 1 file to /ws/sb/myfirstgrailsapp
[copy] copying 1 file to /ws/sb/myfirstgrailsapp
[copy] copying 1 file to /ws/sb/myfirstgrailsapp
[propertyfile] updating property file:
/ws/sb/myfirstgrailsapp/application.properties
created grails application at /ws/sb/myfirstgrailsapp
vivekmz@boson(735)> glassfish/bin/asadmin start-domain
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: hk2 initialized in 281 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: com.sun.enterprise.naming.impl.serviceshookup@51b48197 init done in 307 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: com.sun.enterprise.v3.services.impl.cmdlineparamprocessor@9c0ec97 init done in 310 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: com.sun.enterprise.v3.server.systemtasks@1fd0fafc init done in 382 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: com.sun.enterprise.v3.services.impl.logmanagerservice@388ee016 init done in 411 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: com.sun.enterprise.v3.services.impl.housekeeper@a210b5b init done in 413 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.services.impl.grizzlyproxy start
info: listening on port 8080
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.services.impl.grizzlyproxy start
info: listening on port 8181
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.services.impl.grizzlyproxy start
info: listening on port 4848
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: com.sun.enterprise.v3.services.impl.grizzlyservice@506f9b8e startup done in 630 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: com.sun.enterprise.security.securityservicesutil@585976c2 startup done in 732 ms
mar 7, 2008 7:43:04 pm com.sun.enterprise.v3.server.appserverstartup run
info: glassfish v3 started in 733 ms
vivekmz@boson(558)> cd myfirstgrailsapp/
vivekmz@boson(559)> grails war
now let's deploy to glassfish v3:
vivekmz@boson(749)> ../glassfish/bin/asadmin deploy myfirstgrailsapp-0.1.war
success : myfirstgrailsapp-0.1 deployed successfully
properties=(name=myfirstgrailsapp-0.1)
[#|2008-03-07t20:19:03.580 0000|info|glassfish10.0|javax.enterprise.system.tools.deployment|_threadid=12;_threadname=thread-4;|deployment of myfirstgrailsapp-0.1 done is 9765 ms|#]
now when i accessing http://localhost:8080/myfirstgrailsapp-0.1/ my grails app appears in the firefox:
has been going thru continuous improvements and the development team is busy making it rock solid while adding new features to it. continue sending your feedbacks to .
那年我25,无数个夙兴夜寐,换来一个硕士学位,额上的抬头纹分外明显,脚下却
半步也不敢停歇。如果不想让户口打回原籍,子子孙孙无穷匮,得赶紧地找份留京工作
。你呢?你不着急,魔兽世界和红色警报?早玩腻了!你野心勃勃地筹划着“创业创业
”。当时李彦宏、陈天桥、周云帆,牛人们还没有横空出世,百度、google、完美时空
更是遥远的名词,可青春所向披靡不可一世,你在校园里建起配送网站,大张旗鼓地招
兵买马,大小媒体的记者蜂拥而至。334寝室很快在全楼名噪一时,小姑娘们从天南地
北寄来粉粉的信纸,仰慕地写道:“从报上得知你的精彩故事……”得空,爬上楼顶吹
吹风,你眉飞色舞地转向我,以照顾自己人的口气说,兄弟,一起发财如何?
好呀,可惜,我不能。创业于你,是可进可退可攻可守的棋,启动资金有三姑六眷
帮忙筹集,就算铩羽而归,父母那三室一厅、温暖的灶台也永不落空。失败于我,意味
着覆水难收一败涂地,每年夏天,为了节省三五百块钱的机器钱,爹娘要扛着腰肌劳损
在大日头下收割5亩农田。我穿着借来的西服完成了第一次面试,戴着借来的手表与心
爱的女孩进行了第一次约会。当你拿到了第一笔投资兴奋地报告全班时,我冷静地穿越
大半个北京城,去做最后一份家教。没错,“这活儿技术含量忒低”,但在第一个月工
资下发前,我租来的立锥之地与口粮全靠它维持。
不多久,互联网就遭遇了寒流,你也对创业意兴阑珊,进了家国有性质的通信公司
,我被一家外企聘用。坐井观天的我,竟傻傻地以为扳回了一局。明面上的工资,我比
你超出一截,税后8000,出差住5星级宾馆,一年带薪休假10天。玩命一样地投入工作
,坚信几年后也有个童话般的结尾,“和公主过上幸福的生活”。
好景不长,很快,我明白了为什么大家说白领是句骂人的话。写字楼的套餐,标价
35,几乎没人搭理它。午餐时间,最抢手的是各层拐角处的微波炉,“白领”们端着带
来的便当,排起了长长的队伍。后来,物业允许快餐公司入住,又出现了“千人排队等
丽华”的盛况。这些月入近万的人士节约到抠门的程度。一位同事,10块钱的感冒药都
找保险公司理赔;另一位,在脏乱差的火车站耗上3个小时,为的是18:00后返程能多
得150元的晚餐补助。
这幕幕喜剧未能令我发笑,我读得懂,每个数字后都凝结着加班加点与忍气吞声;
俯首帖耳被老板盘剥,为的是一平米一平米构筑起自己的小窝。白手起家的过程艰辛而
漫长,整整3年,我没休过一次长假没吃过一回鸭脖子;听到“华为25岁员工胡新宇过
劳死”的新闻,也半点儿不觉得惊讶,以血汗、青春换银子的现象在这个行业太普遍了
。下次,当你在上地看见一群人穿着西装革履拎着ibm笔记本奋力挤上4毛钱的公交车,
千万别奇怪,我们就是一群it民工。
惟一让人欣慰的是,我们离理想中的目标一步步靠近。
突如其来地,你的喜讯从天而降:邀请大家周末去新居暖暖房。怎么可能?你竟比
我快?可豁亮的100多平方米、红苹果家具、37寸液晶大彩电无可质疑地摆在眼前。你
轻描淡写地说,老头子给了10万,她家里也给了10万,老催着我们结婚……回家的路上
,女朋友郁郁不说话,她和我一样,来自无名的山城。我揽过她的肩膀,鼓励她也是鼓
励自己,没关系,我们拿时间换空间。
蜜月你在香港过的,轻而易举地花掉了半年的工资,回来说,意思不大,不像tvb
电视里拍的那样美轮美奂;我的婚礼,在家乡的土路、乡亲的围观中巡游,在低矮昏暗
的老房子里拜了天地,在寒冷的土炕上与爱人相拥入眠。幸运的是,多年后黯淡的图景
化作妻子博客里光芒四射的图画,她回味:“有爱的地方,就有天堂。”
我们都想给深爱的女孩以天堂,天堂的含义却迥然不同。你的老婆当上了全职太太
,每天用电驴下载《老友记》和《越狱》;我也想这么来着,老婆不同意,你养我,谁
养我爸妈?不忍心让你一个人养7个人。当你的女孩敷着倩碧面膜舒服地翘起脚,我的
女孩却在人海中顽强地搏杀。
两个人赚钱的速度快得多。到2004年年底,我们也攒到了人生中第一个10万,谁知
中国的楼市在此时被魔鬼唤醒,海啸般狂飙突进,摧毁一切渺小虚弱的个体。2005年3
月,首付还够买西四环的郦城,到7月,只能去南城扫楼了。我们的积蓄本来能买90平
方米的两居来着,9月中旬,仅仅过去2个月,只够买80多平。
没学过经济学原理?没关系。生活生动地阐释了什么叫资产泡沫与流动性泛滥。这
时专家跳出来发言了,“北京房价应该降30%,上海房价应该降40%。”要不,再等等
?我险些栖身于温吞的空方阵营,是你站出来指点迷津:赶快买,房价还会涨。买房的
消息传回老家,爹娘一个劲儿地唏嘘:抵得上俺们忙活半年。在他们看来,7500元一平
方米是不可思议的天价。3年后的2008,师弟们纷纷感叹,你赚大发了,四环内均价1万
4,已无楼可买。
几天前,我看见了水木上一句留言,颇为感慨:“工作5年还没买房真活该,2003
年正是楼市低迷与萧条之时。等到今天,踏空的不仅是黄金楼市,更是整个人生。”
真要感谢你,在我不知理财为何物之时,你早早地告诉我什么叫消费什么叫投资。
并非所有人都拥有前瞻的眼光和投资的观念。许多和我一样来自小地方、只知埋头
苦干的兄弟们,太过关注脚下的麦田,以至于错过一片璀璨的星空。你的理论是,赚钱
是为了花,只有在流通中才能增值,买到喜爱的商品,让生活心旷神怡。而我的农民兄
弟——这里特指是出身农家毕业后留在大城市的兄弟,习惯于把人民币紧紧地捏在手中
。存折数字的增长让他们痴迷。该买房时,他们在租房;该还贷时,他们宁可忍受7%
的贷款利率,也要存上5年的定期。辛苦赚来的银子在等待中缩水贬值。他们往往在房
价的巅峰处,无可奈何地接下最后一棒;也曾天真地许愿,赚够100万就回家买房。可
等到那一天真的到来,老家的房价,二线、三线城市甚至乡镇的都已疯长。
这便是我和你的最大差别,根深蒂固的分歧、不可逾越的鸿沟也在于此。我曾经以
为,学位、薪水、公司名气一样了,我们的人生便一样了。事实上,差别不体现在显而
易见的符号上,而是体现在世世代代的传承里,体现在血液里,体现在头脑中。18年的
积累,家庭出身、生活方式、财务观念,造就了那样一个你,也造就了这样一个我,造
就了你的疏狂佻达与我的保守持重。当我还清贷款时,你买了第二套住房;上证指数
6000点,当我好容易试水成为股民,你清仓离场,转投金市;我每月寄1000元回去,承
担起赡养父母的责任,你笑嘻嘻地说,养老,我不啃老就不错了;当我思考着要不要生
孩子、养孩子的成本会在多大程度上折损生活品质时,4个老人已出钱出力帮你抚养起
独二代;黄金周去一趟九寨沟挺好的了,你不满足,你说德国太拘谨美国太随意法国才
是你向往的时尚之都……
我的故事,是一代“移民”的真实写照——迫不得已离乡背井,祖国幅员辽阔,我
却像候鸟一样辗转迁徙,择木而栖。现行的社会体制,注定了大城市拥有更丰富的教育
资源、医疗资源、生活便利。即便取得了一纸户口,跻身融入的过程依然是充满煎熬,
5年、10年乃至更长时间的奋斗才获得土著们唾手可得的一切。曾经愤慨过,追寻过,
如今,却学会了不再抱怨,在一个又一个缝隙间心平气和。差距固然存在,但并不令人
遗憾,正是差距和为弥补差距所付出的努力,加强了生命的张力,使其更有层次更加多
元。
可以想见的未来是,有一天我们的后代会相聚于迪斯尼(这点自信我还是有的),
讲起父亲的故事,我的那一个,虽然不一定更精致更华彩,无疑曲折有趣得多。那个故
事,关于独立、勇气、绝地反弹、起死回生,我给不起儿子名车豪宅,却能给他一个不
断成长的心灵。我要跟他说,无论贫穷富贵,百万家资或颠沛流离,都要一样地从容豁
达。
至此,喝不喝咖啡又有什么打紧呢?生活姿态的优雅与否,不取决于你所坐的位置
、所持的器皿、所付的茶资。它取决于你品茗的态度。
我奋斗了18年,不是为了和你一起喝咖啡。
二、基本概念
httpsessioncontextintegrationfilter 存储securitycontext in httpsession
channelprocessingfilter 重定向到另一种协议,如http到https
concurrentsessionfilter 因为不使用任何securitycontextholder的功能,但是需要更新sessionregistry来表示当前的发送请求的principal,通过在web.xml中注册listener监听session事件,并发布相关消息,然后由sessionregistry获得消息以判断当前用户的session数量。
authenticationprocessingfilter 普通认证机制(大多数用这个)
casprocessingfilter cas认证机制
basicprocessingfilter http协议的basic认证机制
httprequestintegrationfilter authentication 从容器的httpservletrequest.getuserprincipal()获得
jbossintegrationfilter 与jboss相关。
securitycontextholderawarerequestfilter 与servlet容器结合使用。
remembermeprocessingfilter 基于cookies方式进行认证。
anonymousprocessingfilter 匿名认证。
exceptiontranslationfilter 捕获所有的acegi security 异常,这样要么返回一个http错误响应或者加载一个对应的authenticationentrypoint
authenticationentrypoint 认证入口
三、acegi认证授权流程
1、filtertobeanproxy 负责代理请求给filterchainproxy
2、filterchainproxy 方便的将多个filter串联起来,如上面基本概念中提到的各种filter,当然如果对uri进行授权保护,也可以包含filtersecurityinterceptor。注意各filter的顺序。
3、abstractsecurityinterceptor 调度中心。负责调用各模块完成相应功能。
filtersecurityinterceptor 对uri进行拦截保护
aspectjsecurityinterceptor 对方法进行拦截保护
methodsecurityinterceptor 对方法进行拦截保护
4、authenticationmanager 用户认证
-> authenticationprovider 实际进行用户认证的地方(多个)。
-> userdetailsservice 返回带有grantedauthority的userdetail或者抛出异常。
5、accessdecisionmanager(unanimousbased/affirmativebased/consensusbased) 授权
-> accessdecisionvoter(rolevoter/baseaclentryvoter) 实际投票的voter(多个).
6、runasmanager 变更grantedauthority
7、afterinvocationmanager 变更返回的对象
-> baseinvocationprovider 实际完成返回对象变更的地方(多个)。
图 1 acegi体系结构
securitycontextholder是框架级的容器,它保存着和所有用户关联securitycontext实例, securitycontext承载着用户(也称认证主体)的身份信息的权限信息, authenticationmanager、accessdecisionmanager将据此进行安全访问控制。
securitycontext的认证主体安全信息在一个http请求线程的多个调用之间是共享的(通过threadlocal),但它不能在多个请求之 间保持共享。为了解决这个问题,acegi将认证主体安全信息缓存于httpsession中,当用户请求一个受限的资源时,acegi通过 httpsessioncontextintegrationfilter将认证主体信息从httpsession中加载到 securitycontext实例中,认证主体关联的securitycontext实例保存在acegi容器级的 securitycontextholder里。当请求结束之后,httpsessioncontextintegrationfilter执行相反的操 作,将securitycontext中的认证主体安全信息重新转存到httpsession中,然后从securitycontextholder中清 除对应的securitycontext实例。通过httpsession转存机制,用户的安全信息就可以在多个http请求间共享,同时保证 securitycontextholder中仅保存当前有用的用户安全信息,其整体过程如图 2所示:
图 2 securitycontext在httpsession和请求线程间的转交过程
当用户请求一个受限的资源时,authenticationmanager首先开始工作,它象一个安检入口,对用户身份进行核查,用户必须提供身份认证的 凭证(一般是用户名/密码)。在进行身份认证时,authenticationmanager将身份认证的工作委托给多个 authenticationprovider。因为在具体的系统中,用户身份可能存储在不同的用户信息安全系统中(如数据库、ca中心、ldap服务 器),不同用户信息安全系统需要不同的authenticationprovider执行诸如用户信息查询、用户身份判断、用户授权信息获取等工作。只要 有一个authenticationprovider可以识别用户的身份,authenticationmanager就通过用户身份认证,并将用户的授 权信息放入到securitycontext中。
当用户通过身份认证后,试图访问某个受限的程序资源时,accessdecisionmanager开始工作。 accessdecisionmanager采用民主决策机制判断用户是否有权访问目标程序资源,它包含了多个accessdecisionvoter。 在访问决策时每个accessdecisionvoter都拥有投票权,accessdecisionmanager统计投票结果,并按照某种决策方式根 据这些投票结果决定最终是否向用户开放受限资源的访问。
图 3 用户和权限
在未使用acegi之前,我们可能通过类似user、customer等领域对象表示用户的概念,并在程序中编写相应的用户认证的逻辑。现在,你要做的一 个调整是让原先这些代表用户概念的领域类实现userdetails接口,这样,acegi就可以通过userdetails接口访问到用户的信息了。
userdetails可能从数据库、ldap等用户信息资源中返回,这要求有一种机制来完成这项工作,userdetailsservice正是充当这 一角色的接口。userdetailsservice接口很简单,仅有一个方法:userdetails loaduserbyusername(string username) ,这个方法通过用户名获取整个userdetails对象。
authentication代表一个和应用程序交互的待认证用户,acegi从类似于登录页面、cookie等处获取待认证的用户信息(一般是用户名密码)自动构造authentication实例。
图 4 acegi的认证用户
图 5 认证用户信息存储器
图 6 abstractsecurityinterceptor工作流程
安全对象和一般对象的区别在于前者通过acegi的“配置属性”进行了描述,如“/view.jsp=priv_common”配置属性就将 “/view.jsp”这个url资源标识为安全对象,它表示用户在访问/view.jsp时,必须拥有priv_common这个权限。配置属性通过 xml配置文件,注解、数据库等方式提供。安全对象通过配置属性表示为一个权限,这样,acegi就可以根据authentication的权限信息获知 用户可以访问的哪些安全对象。
根据安全对象的性质以及具体实现技术,abstractsecurityinterceptor拥有以下三个实现类:
filtersecurityinterceptor:对url资源的安全对象进行调用时,通过该拦截器实施环绕切面。该拦截器使用servlet过滤器实现aop切面,它本身就是一个servlet过滤器;
methodsecurityinterceptor:当调用业务类方法的安全对象时,可通过该拦截器类实施环绕切面;
aspectjsecurityinterceptor:和methodsecurityinterceptor类似,它是针对业务类方法的拦截器,只不过它通过aspectj实施aop切面。
如何使用管道流:管道用于将一个线程的输出连接到另一个线程的输入
如何封装流:流经常被以下的这种形式封装起来,以便组合许多流的各种功能
对象的串行化:java.io包中的两个流——objectinputstream和objectoutputstream是字节流,他们的工作与其他输入和输出流类似。但他们的特殊之处在于它们可以读写对象。
对对象进行串行化:如果将一个不能串行化的对象传递给writeobject方法,那么它抛出一个notserializable exception。对象只能在它的类实现了serializable接口的情况下被串行化。
为类提供对象串行化:只有在对象的类实现了serializable接口情况下,对象才是可串行化的。所有,如果想要对你的类的实例进串行化,这个类必须实现serializable接口。serializable接口是一个空接口,也就是说,他不包含任何方法声明;它的作用只是表明这个类的对象可以被串行化。
i/o复制小程序(copy.java),如下:
import java.io.file;
import java.io.filereader;
import java.io.filewriter;
import java.io.ioexception;
//以上是此程序用到的io类的包,也可以用“import java.io.*”
public class copy {
public static void main(string[] args) throws ioexception {
file inputfile = new file("d:\\temp\\helloworld.java"); //目标文件路径,java中路径地址只能用“\\”或“/”不能使用“\”
file outputfile = new file("d:\\temp\\outagain.java"); //复制后新文件保存路径
filereader in = new filereader(inputfile);
filewriter out = new filewriter(outputfile);
int c;
while ((c = in.read()) != -1) //一直循环到0表示已经复制完毕,所以这里使用不等于负1
out.write(c);
in.close(); //关闭读文件对象
out.close(); //关闭写文件对象
}
这个对于seam 1.2 用户来说是个好消息,因为我们现在完全支持创建eclipse wtp兼容包括seam 1.2.1的seam组件热部署项目。增加完全增量异步部署到jboss as server中,你能得到既快又好的部署环境。
该发布版也支持hibernate tools用户的一些新功能和其他的bug修复。你能阅读 这篇文章了解它们。
尽管现在还不支持seam 2的项目创建向导,但是代码完成和seam视图能和seam 2相容。仅需要右击项目增加seam支持。大家赶紧试一下啊,seam可是将来的主流啊。