??xml version="1.0" encoding="utf-8" standalone="yes"?> 切面QAspectQ?/em>Q?一个关注点的模块化Q这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子?在Spring AOP中,切面可以使用通用c(Z模式的风| 或者在普通类中以 q接点(JoinpointQ?/em>Q?在程序执行过E中某个特定的点Q比如某Ҏ调用的时候或者处理异常的时候?在Spring AOP中,一个连接点 L 代表一个方法的执行?通过声明一?code class=interfacename>org.aspectj.lang.JoinPointcd的参数可以通知QAdviceQ的M部分获得q接点信息? 通知QAdviceQ?/em>Q?在切面的某个特定的连接点QJoinpointQ上执行的动作。通知有各U类型,其中包括“around”?#8220;before”?#8220;after”{通知?通知的类型将在后面部分进行讨论。许多AOP框架Q包括SpringQ都是以拦截?/em>做通知模型Q?q维护一个以q接点ؓ中心的拦截器链? 切入点(PointcutQ?/em>Q?匚wq接点(JoinpointQ的断言。通知和一个切入点表达式关联,q在满q个切入点的q接点上q行Q例如,当执行某个特定名U的ҎӞ?切入点表辑ּ如何和连接点匚w是AOP的核心:Spring~省使用AspectJ切入点语法? 引入QIntroductionQ?/em>Q?Q也被称为内部类型声明(inter-type declarationQ)。声明额外的Ҏ或者某个类型的字段?Spring允许引入新的接口Q以及一个对应的实现Q到M被代理的对象?例如Q你可以使用一个引入来使bean实现 目标对象QTarget ObjectQ?/em>Q?被一个或者多个切面(aspectQ所通知QadviseQ的对象。也有h把它叫做 被通知QadvisedQ?/em> 对象?既然Spring AOP是通过q行时代理实现的Q这个对象永q是一?被代理(proxiedQ?/em> 对象? AOP代理QAOP ProxyQ?/em>Q?AOP框架创徏的对象,用来实现切面契约Qaspect contractQ(包括通知Ҏ执行{功能)?在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理?注意QSpring 2.0最新引入的Z模式Qschema-basedQ风格和@AspectJ注解风格的切面声明,对于使用q些风格的用h_代理的创建是透明的? l入QWeavingQ?/em>Q?把切面(aspectQ连接到其它的应用程序类型或者对象上Qƈ创徏一个被通知QadvisedQ的对象?q些可以在编译时Q例如用AspectJ~译器)Q类加蝲时和q行时完成?Spring和其他纯Java AOP框架一P在运行时完成l入? 前置通知QBefore adviceQ?/em>Q?在某q接点(join pointQ之前执行的通知Q但q个通知不能Lq接点前的执行(除非它抛Z个异常)? q回后通知QAfter returning adviceQ?/em>Q?在某q接点(join pointQ正常完成后执行的通知Q例如,一个方法没有抛ZQ何异常,正常q回? 抛出异常后通知QAfter throwing adviceQ?/em>Q?在方法抛出异帔R出时执行的通知? 后通知QAfter (finally) adviceQ?/em>Q?当某q接炚w出的时候执行的通知Q不论是正常q回q是异常退出)? 环绕通知QAround AdviceQ?/em>Q?包围一个连接点Qjoin pointQ的通知Q如Ҏ调用。这是最强大的一U通知cd?环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否l箋执行q接Ҏ直接q回它们自己的返回值或抛出异常来结束执行?
]]>
1.取得oscache.jar 文g攑ֈ /WEB-INF/lib 或相应类库目?目录中?br> 2.oscache.jar依赖commons-collections.jar包。如果你的jdk版本?.3,
在lib中加入Apache Common Lib 的commons-collections.jar包?br> 如jdk?.4以上则不必要?br> 3.src根目录或发布环境?WEB-INF/classes 目录下放入oscache.properties?br>
cache.memory
gؓtrue ?false Q默认ؓ在内存中作缓存,
如设|ؓfalseQ那cache只能~存到数据库或硬盘中Q那cacheq有什么意义:Q?br>
cache.capacity
~存元素个数
cache.persistence.class
持久化缓存类Q如此类打开Q则必须讄cache.path信息
cache.cluster 相关
为集设|信息?br> 如cache.cluster.multicast.ip为广播IP地址
cache.cluster.properties为集属?br>
cache.path
盘持久化时存放文g的目录。如果目录不存在OSCache会自动创建?br>WindowspȝQc:\\myapp\\cache。其它:/opt/myapp/cache
cache.persistence.overflow.only*
是否只有当指定的内存~存已经满时才进行持久化。推荐用trueQflase是ؓ向后兼容?br>
cache.unlimited.disk
盘~存是否有限制。缺省ؓcache.capacity指定的?br>
q用Q?br> com.opensymphony.oscache.general.GeneralCacheAdministrator
GeneralCacheAdministrator主要对实现持久化对象的保存以及取出的相关的操作?br>
Object getFromCacheQString keyQ?nbsp; //Ҏkey获取~存对象
Object getFromCacheQString key , int refreshIntervalQ?/refreshInterval旉内,Ҏkey获取~存对象
void putInCache(String key ,Object obj) //保存被缓存对?br>void flushAll() //删除所有被~存的对?br>void flushAll(Date date) //在指定的旉d除所有被~存的对?br>void cancelUpdate(String key) //取消未确定的更新
Java代码
2
3 import java.io.BufferedInputStream;
4 import java.io.BufferedOutputStream;
5 import java.io.File;
6 import java.io.FileInputStream;
7 import java.io.IOException;
8 import java.text.SimpleDateFormat;
9 import java.util.Date;
10
11 import javax.servlet.ServletException;
12 import javax.servlet.http.HttpServlet;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15 import javax.servlet.http.HttpSession;
16
17 import com.opensymphony.oscache.base.NeedsRefreshException;
18 import com.opensymphony.oscache.general.GeneralCacheAdministrator;
19
20
21 public class DisplayChart extends HttpServlet {
22
23 /**
24 * Default constructor.
25 */
26 public DisplayChart() {
27 super();
28 }
29
30 /**
31 * Init method.
32 *
33 * @throws ServletException never.
34 */
35 public void init() throws ServletException {
36 return;
37 }
38
39
40 public static GeneralCacheAdministrator cacheAdmin = new GeneralCacheAdministrator();
41 public void service(HttpServletRequest request,
42 HttpServletResponse response)
43 throws ServletException, IOException {
44
45 String path = getServletContext().getRealPath("/");
46 File file = null;
47 SimpleDateFormat sdf= new SimpleDateFormat("hh-mm-ss");
48 try {
49 file = (File)cacheAdmin.getFromCache(sdf.format(new Date()));
50 System.out.println("来自~存!"+ sdf.format(new Date()));
51 } catch (NeedsRefreshException e) {
52 file = new File(path+"xmls\\Pipe11.xml");
53 cacheAdmin.putInCache(sdf.format(new Date()), file);
54 System.out.println("--~存没有!"+sdf.format(new Date()));
55 }
56 sendResponse(file,response);
57 return;
58 }
59 /**
60 * 把文件用响应写?nbsp;
61 * @param file
62 * @param response
63 * @throws IOException
64 */
65 public void sendResponse(File file,HttpServletResponse response) throws IOException{
66 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
67 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
68 byte[] input = new byte[1024];
69 boolean eof = false;
70 while (!eof) {
71 int length = bis.read(input);
72 if (length == -1) {
73 eof = true;
74 }
75 else {
76 bos.write(input, 0, length);
77 }
78 }
79 bos.flush();
80 bis.close();
81 bos.close();
82 }
83
84 }
85
]]>
private Singleton(){}
//在自己内部定义自׃个实例,是不是很奇怪?
//注意q是private 只供内部调用
private static Singleton instance = new Singleton();
//q里提供了一个供外部讉K本class的静态方法,可以直接讉K
public static Singleton getInstance() {
return instance;
}
}
private static Singleton instance = null;
public static synchronized Singleton getInstance() {
//q个Ҏ比上面有所改进Q不用每ơ都q行生成对象Q只是第一?nbsp;
//使用时生成实例,提高了效率!
if (instance==null) instanceQ?/span>new Singleton();
return instance;
}
}
使用Singleton.getInstance()可以讉K单态类?nbsp;
上面W二中Ş式就是lazy initializationQ也是说第一ơ调用时初始SingletonQ以后就不用再生成了?nbsp;
注意到lazy initialization形式中的synchronizedQ这个synchronized很重要,如果没有synchronizedQ那么用getInstance()是有可能得到多个Singleton实例?br>
那么Z么只有用synchronized关键字才可以辑ֈ单态的目的呢?synchronized到底有什么含义呢Q?br> synchronized 关键字,它包括两U用法:synchronized Ҏ?synchronized 块?
1. synchronized ҎQ通过在方法声明中加入 synchronized关键字来声明 synchronized Ҏ。如Q?
?Java 中,不光是类实例Q每一个类也对应一把锁Q这h们也可将cȝ静态成员函数声明ؓ synchronized Q以控制其对cȝ静态成员变量的讉K?nbsp;
synchronized Ҏ的缺P若将一个大的方法声明ؓsynchronized 会大大影响效率Q典型地Q若线E类的方?run() 声明?synchronized Q由于在U程的整个生命期内它一直在q行Q因此将D它对本类M synchronized Ҏ的调用都永远不会成功。当然我们可以通过访问类成员变量的代码放C门的Ҏ中,其声明?synchronized Qƈ在主Ҏ中调用来解决q一问题Q但?Java 为我们提供了更好的解军_法,那就?synchronized 块?
2. synchronized ?/strong>Q通过 synchronized关键字来声明synchronized 块。语法如下:
//允许讉K控制的代?nbsp;
}
对synchronized(this)的一些理?br>
一、当两个q发U程讉K同一个对象object中的q个synchronized(this)同步代码块时Q一个时间内只能有一个线E得到执行。另一个线E必ȝ待当前线E执行完q个代码块以后才能执行该代码块?
二、然而,当一个线E访问object的一个synchronized(this)同步代码块时Q另一个线E仍然可以访问该object中的非synchronized(this)同步代码块?
三、尤其关键的是,当一个线E访问object的一个synchronized(this)同步代码块时Q其他线E对object中所有其它synchronized(this)同步代码块的讉K被d?
四、第三个例子同样适用其它同步代码块。也是_当一个线E访问object的一个synchronized(this)同步代码块时Q它p得了q个object的对象锁。结果,其它U程对该object对象所有同步代码部分的讉K都被暂时d?
五、以上规则对其它对象锁同样适用
]]>
通知的类型:@Aspect
注解Q?code class=interfacename>@AspectJ风格Q来实现?IsModified
接口Q以便简化缓存机制?
]]>
一 插入?/span>:遍历排序集合Q每C个元素时Q都要将q个元素与所有它之前的元素遍历比较一遍,让符合排序顺序的元素挨个Ud到当前范围内它最应该出现的位|。交换是盔R遍历UdQ双重@环控制实?/span>.q种排序法属于地头蛇cd,在我的地牌上我要把所有的东西按一定的序规整,q来一?/span>,规整一?/span>.
处理代码如下:
二冒泡法:比较ҎQ它的内层@环保证遍历一ơ后Q集合中最(大)元素出现在它的正位|,下一ơ就是次元素。。。该Ҏ在集合分布的各种情况下交换移动的ơ数基本不变Q属于最慢的一U排序。实C是双重@环控制。这U排序法属于q江?/span>,是要找到极?/span>,但是q奖龙也有大?/span>,二哥{?/span>,所以他们只能是大哥挑了二哥?/span>.
处理代码如下:
三选择?/span>:该方法只是通过遍历集合记录最(大)元素的位|,一ơ遍历完后,再进行交换位|操作,cM冒Q但在比较过E中Q不q行交换操作Q只记录元素位置。一ơ遍历只q行一ơ交换操作。这个对与交换次序比较费时的元素比较适合。这U排序法比冒泡法要城府要q?/span>,我先C极端数据,待遍历数据完了之?/span>,我再处理,不像冒法那样只要比自己极端一点的p处理,选择法只处理本n范围内的最极端数据.
?/span> Shell排序Q?/span>
它是Ҏ入排序的一U改q,是考虑集合元素按照一定的基数划分成组L序,让每一l在局部范围内先排成基本有序,最后在q行一ơ所有元素的插入排序?/span>
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1630773
来多人开始用JavaQ但是他们大多数人没有做好够的思想准备(没有接受OO思想体系相关培训)Q以致不能很好驾驭Java目Q甚?D开发后的Javapȝ性能~慢甚至l常当机。很多h觉得q是Java复杂DQ其实根本原因在于:我们原先掌握的关于Y件知?OO斚w)不是太乏就是不恰当Q存在认识上和方法上的误区?/p>
软g的生命?/strong>
软g是有生命的,q可能是老调重弹了,但是因ؓ它事兛_层架构的原由Q反复强调都不过分?/p>
一个有生命的Y仉先必L一个灵zd扩展的基架构Q其ơ才是完整的功能?/p>
目前很多人对软g的思想q是焦点落在后者:完整的功能,觉得一个Y件功能越完整好Q其实关键还是架构的灉|性,是前者,基础架构好,功能d只是旉和工作量问题Q但是如果架构不好,功能再完_也不可能包括未来所有功能,软g是有生命的,在未来成长时Q更多功能需要加入,但是因ؓ基础架构不灵zM能方便加入,死\一条?br>
正因为普通h对Y件存在短视误区,对功能追求高于基架构Q很多吃了亏的老程序员此d软g行业Q带走宝늚p|l验Q新的盲目的q轻E序员还是用老的思维往前冲。其实很多国外免费开源框架如ofbiz compiere和slide也存在这斚w陷阱Q貌似非常符合胃口,其实cM国内那些几百元的盗版软gQ扩展性以及持l发展性严重不?/p>
那么选择现在一些流行的框架如Hibernate、Spring/Jdonframework是否pC基架构打好了呢Q其实还不尽Ӟ关键q是取决于你如何使用q些框架来搭Z的业务系l?/p>
存储q程和复杂SQL语句的陷?/strong>
首先谈谈存储q程使用的误区,使用存储q程架构的h以ؓ可以解决性能问题Q其实它正是D性能问题的罪祸首之一Q打个比喻:如果一个h频MQ打一针可以让其g长半q_但是打了q针Q其他所有医疗方案就全部失效Q请问你会用这U短视方案吗Q?/p>
Z么这栯呢?如果存储q程都封装了业务q程Q那么运行负载都集中在数据库端,要中间J2EE应用服务器干什么?要中间服务器的分布式计算和集能力做什么?只能回到q去集中式数据库L时代。现在Y仉是面向互联网的,不象q去那样局限在一个小局域网Q多用户q发讉K量都是无法确定和衡量Q依靠一台数据库L昄是不能够承受q样恶劣的用戯问环境的。(当然搞数据库集群也只是五十步和百步的区别Q?/p>
从分层角度来看,现在三层架构Q表现层、业务层和持久层Q三个层ơ应该分割明显,职责分明Q持久层职责持久化保存业务模型对象,业务层对持久层的调用只是帮助我们ȀzLl委托其保管的对象,所以,不能因ؓ持久层是保管者,我们׃其ؓ核心围绕其编E,除了要求其归q模型对象外Q还要求其做其做复杂的业务组合。打个比喻:你在火R站将水果和盘子两个对象委托保处保管Q过了两天来取时Q你q要求保处水果去皮切成块Q放在盘子里Q做成水果盘l你Q合理吗Q?/p>
上面是谈q分依赖持久层的一个现象,q有一个正好相反现象,持久层散发出来,开始挤占业务层Q腐蚀业务层,整个业务层到处看见的是数据表的媄子(包括数据表的字段Q,而不是业务对象。这L序员应该多看?a target=_blank>OOl典PoEAA?a target=_blank>PoEAA 认ؓ除了持久层,不应该在其他地方看到数据表或表字D名?/p>
当然适量使用存储q程Q用数据库优点也是允许的。按照Evans DDD理论Q可以将SQL语句和存储过E作则Specification一部分?
Hibernate{ORM问题
现在使用HibernateZ不少Q但是他们发现Hibernate性能~慢Q所以寻求解x案,其实q不?Hibernate性能~慢Q而是我们使用方式发生错误Q?/p>
“最q本人正搞一个项目,目中我们用Cstruts1.2+hibernate3, ׃关系复杂表和表之间的关系很多Q在很多地方把lazy都设|falseQ所以导致数据一加蝲很慢Q而且查询一条数据更是非常的慢?#8221;
Hibernate是一个基于对象模型持久化的技术,因此Q关键是我们需要设计出高质量的对象模型Q遵循DDD领域建模原则Q减降低关联,通过分层{有效办法处理关联。如果采取围l数据表q行设计~程Q加上表之间关系复杂Q没有科学方法处理、侦察或减少q些关系Q,必然D pȝq行~慢Q其实同样问题也适用于当初对EJB的实体Bean的CMP抱怨上Q实体Bean是Domain Model持久化,如果不首先设计Domain ModelQ而是设计数据表,和持久化工具设计目标背道而驰Q能不出问题吗?关于q个问题N多年在Jdon争论q?/p>
q里同样延出另外一个问题:数据库设计问题,数据库是否需要在目开始设计?
如果我们q行数据库设计,那么׃生了一pd问题Q当我们使用Hibernate实现持久保存Ӟ必须考虑事先设计好的数据库表l构以及他们的关pd何和业务对象实现映射Q这实际上是非常隑֮现的Q这也是很多得用ORM框架手Ҏ原因所在?/p>
当然Q也有脑力相当发辄人可?实现Q但是这U围l数据库实现映射的结果必然扭曲业务对象,q类g两个板块Q数据表和业务对象)相撞Q必然生地震,地震的结果是两|׃Q?软的一方吃亏,业务对象是代码,相当于数据表l构Q属于Y的一方,最后导致业务对象变成数据传输对象DTO, DTO满天飞,性能和维护问题随之而来?/p>
领域建模解决了上qC多不协调问题Q特别是ORM痛苦使用问题Q关于ORM/Hibernate使用q是那句老话Q如果你不掌握领域徏模方法,那么׃要用HibernateQ对于这个层ơ的你:也许No ORM 更是一个简单之道: No ORM: The simplest solution
http://www.theserverside.com/blogs/thread.tss?thread_id=41715
Spring分层矛盾问题
Spring是以挑战EJB面貌出现Q其本n拥有的强大组件定制功能是优点Q但是存在实战的一些问题,Spring作ؓ业务层框Ӟ不支持业务层Session 功能?/p>
具体举例如下Q当我们实现购物车之cM务功能时Q需要将购物场合保存到Session中,׃业务层没有方便的Session支持Q我们只得将购物车保存到 HttpSessionQ而HttpSession只有通过HttpRequest才能获得Q再因ؓ在Spring业务层容器中是无法访问到HttpRequestq个对象的,所以, 最后我们只能将“购物车保存到HttpSession”q个功能攑֜表现层中实现Q而这个功能明昑ֺ该属于业务层功能Q这导致我们的Java目层次混ؕQ维护性差?q背了用Spring和分层架构最初目的?/p>
相关案例Q请教一个在完整提交前时保存的问题:
http://www.jdon.com/jive/article.jsp?forum=46&thread=28429
领域驱动设计DDD
现在回到我们讨论的重点上来,分层架构是我们用Java的根本原因之一Q域建模专家Eric Evans在他?#8220;Domain Model Design”一书中开首先强调的是分层架构,整个DDD理论实际是告诉我们如何用模型对象oo技术和分层架构来设计实C个Java目?/p>
我们现在很多人知道Java目基本有三层:表现层 业务层和持久层,当我们执著于讨论各层框架如何选择之时Q实际上我们真正的项目开发工作还没有开始, 是我们选定了某U框架的l合Q如Struts+Spring+Hibernate或Struts+EJB或Struts+JdonFrameworkQ,我们q没有意识到业务层工作还需要大量工作,DDD提供了在业务层中再划分新的层ơ思想Q如领域层和服务层,甚至再细分ؓ作业层、能力层、策略层{等。通过层次l化方式辑ֈ复杂软g的松耦合。DDD提供了如何细分层ơ的方式
当我们将_֊p在架构技术层面的讨论和研I上Ӟ我们可能忘记以何U依据选择q些架构技术?选择标准是什么?领域驱动设计DDD 回答了这L问题QDDD会告诉你如果一个框架不能协助你实现分层架构Q那抛弃它Q同ӞDDD也指出选择框架的考虑目的Q得你不会 Z亦云Q陷入复杂的技术细节迷雾中Q迷׃架构选择的根本方向?/p>
现在也有些h误以为DDD是一U新的理论,其实DDD和设计模式一P不是一U新的理论,而是实战l验的ȝQ它前?使用面向模型设计的方法经验提炼出来,供后来者学习,以便q速找到驾驭我们Y仉目的Ҏ之道?/p>
现在Evans DDD概念很火Q因为它著名的PoEAAq行了具化,实现?a target=_blank>PoEAA可操作性,q也是MF大力推崇的原因。最q?8??一位老外博客上用微Y?NET架构和Evans DDD比较的文章:http://weblogs.asp.net/pgielens/archive/2006/08/08/Organizing-Domain-Logic.aspxQ这文章比较了微Y的三层服务应用架构[Microsoft TLSA]和Evans DDD的架构, 使用Microsoft .NET Pet Shop 4Z子,解释两个目标的区别,q且表明
微Y是如何在案例中更好地实现支持后者。这文章帮助哪?NETq_上有域设计知识的人实现更好地提高?/p>
另外一本关?NET的DDD书籍也已l出版,q些都说明Evans DDDq把火已l烧?NET领域Q当然DDD在Java领域生根开花多q_Evans的DDD书籍是以JavaZ子的Q笔者板桥里Z率先?005q推出DDD框架JdonFramework 1.3版本Q这些都说明QJava在整个Y件业先进思想的实践上L领先一步?br>
参考文章:
实战DDD(Domain-Driven Design领域驱动设计)
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1630894