Apache Ivy

http://www.ibm.com/developerworks/cn/java/j-ap05068/
Apache Ivy
  Apache Ivy 是Apache Ant 下的一个子项目,最新版本是2009年1月20日发布的2.0.0正式版。Apache Ivy是一个优秀的管理(记录、跟踪、解析和报告)项目依赖的工具,提供了强大的依赖管理功能,可与Apache Ant紧密集成。
  值得注意的功能有:
  1。能够和Apache Ant紧密集成
  2。支持多个不同的依赖存储
  3。依赖报告Dependency Reporting
  4。支持持续集成
  5。强大的冲突管理功能。
  Maven和Ivy的区别 :
  Maven2,它是一个模块化项目构建工具(Building a Project )。它能够管理依赖、构建周期、测试、打包并且在仓库中发布你的制品。它是一个项目构建工具,领先于通常的构建工具(实际上它的第一个版本是在Ant之上的一层)。apacheivy2 对项目依赖的文件可以进行统一的管理,依赖于ant,它是一个管理(记录、跟踪、解析和报告)项目依赖的工具 (dependencytool).

JDBC事务和JTA (XA)事务区别

简单的说 jta是多库的事务 jdbc是单库的事务

JTA提供了跨数据库连接(或其他JTA资源)的事务管理能力。这一点是与JDBC Transaction最大的差异。
JDBC事务由Connnection管理,也就是说,事务管理实际上是在JDBC Connection中实现。事务周期限于Connection的生命周期。

JDBC 事务
JDBC 事务是用 Connection 对象控制的。JDBC Connection 接口( java.sql.Connection )提供了两种事务模式:自动提交和手工提交。
★ 在jdbc中,事务操作缺省是自动提交。也就是说,一条对数据库的更新表达式代表一项事务操作,操作成功后,系统将自动调用commit()来提交,否则将调用rollback()来回滚。
★ 在jdbc中,可以通过调用setAutoCommit(false)来禁止自动提交。之后就可以把多个数据库操作的表达式作为一个事务,在操作完成后调 用commit()来进行整体提交,倘若其中一个表达式操作失败,都不会执行到commit(),并且将产生响应的异常;此时就可以在异常捕获时调用 rollback()进行回滚。这样做可以保持多次更新操作后,相关数据的一致性
★JDBC 事务的一个缺点是事务的范围局限于一个数据库连接。一个 JDBC 事务不能跨越多个数据库。

JTA事务
JTA(Java Transaction API) 为 J2EE 平台提供了分布式事务服务。
★ 要用 JTA 进行事务界定,应用程序要调用 javax.transaction.UserTransaction 接口中的方法。例如:
utx.begin();
// ...
DataSource ds = obtainXADataSource();
Connection conn = ds.getConnection();
pstmt = conn.prepareStatement("UPDATE MOVIES ...");
pstmt.setString(1, "Spinal Tap");
pstmt.executeUpdate();
// ...
utx.commit();

选择最好的方式

我们讨论了如何用 JDBC 和 JTA 界定事务。每一种方式都有其优点,您需要决定哪一种最适合于您的应用程序。

在最近的许多项目中,我们小组是用 JDBC API 进事务界定来构建 DAO 类的。这些 DAO 类可以总结如下:

  • 事务界定代码嵌入在 DAO 类中。
  • DAO 类使用 JDBC API 进行事务界定。
  • 调用者不能界定事务。
  • 事务范围局限于单个 JDBC 连接。

JDBC 事务并不总是适合复杂的企业应用程序。如果您的事务要跨越多个 DAO 或者多个数据库,那么下列实现策略也许更合适:

  • 事务用 JTA 界定。
  • 事务界定代码从 DAO 中分离出来。
  • 调用者负责界定事务。
  • DAO 加入一个全局事务。

JDBC 方式由于其简单性而具有吸引力,JTA 方式提供了更大的灵活性。您所选择的实现将取决于应用程序的特定需求。

引用:高级 DAO 编程http://www.ibm.com/developerworks/cn/java/j-dao/
http://www.51cto.com/specbook/24/6924.htm

《设计模式之禅》读书笔记

六大设计原则
单一职责原则 Single Responsibility Principle
例子:
IPhone :
-IConnectionManager
-DataTranfer
There should never be more than one reason for a class to change.
两个职责变化不互相影响,就考虑分成两个接口
降低复杂度、可读、可维护
用职责和变化原因来衡量接口或类设计得是否优良,但是,“职责”和“变化原因”都是不可度量的!
实践:
很难落实,各种现实原因(This is sometimes hard to see)
方法职责单一
接口单一职责,类的设计尽量做到只有一个原因引起变化
 
里氏替换原则 Likov Substitution Principle
If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T ,the behavior of P is unchanged when o1 is substituted for o2 then S is a subtype of T.
Program P 中 S o1 能替换所有的 T o2 , S是T的子类
1.子类必须完全实现父类方法:在类中调用其他类时候,务必要使用父类或接口,如果不能使用父类或接口,说明类的设计已经违背了LSP法则
场景:士兵 枪 射击
枪有很多种,所有枪继承一个抽象的枪,士兵在使用具体枪的时候,调用抽象枪里的方法
玩具枪不能射击,怎么办?
1).所有士兵都做判断 instanceof
2).建一个抽象玩具枪类,与抽象枪类建立关联委托关系,将一些都交给抽象枪处理,具体场景在处理
2. 子类可以有自己的个性
downcast(向下转型)是不安全的,里氏替换原则来看,就是有子类出现的地方父类未必就可以出现
3.覆盖或实现父类的方法是输入参数可以被放大
Design by Contract 契约设计:父类和接口
当放大的时候就不是覆写(Override),而是重载(Overload),这时前置条件小的就会被执行,
如果子类前提小,那么在没有覆盖的前提下,子类方法就会代替父类方法被执行,这将引起业务的混乱
4.覆写或实现父类的方法时输出结果可以被缩小
依赖倒置原则(Dependence Inversion Principle)
High level modules should not depend upon low level modules ,both should depend upon abstractions.
Abstractions should not depend upon details.
Details should depend upon abstraction
核心:OID ->OOD 面向接口设计
TDD Test-Driven Development : 写好单元测试类,然后再写实现类。适合研发类项目和项目成员水平较低的时候使用
JMock 抽象出虚拟对象进行测试
依赖注入的三种写法
1.构造函数注入
2.Setter方法传递依赖对象
3.接口声明依赖对象:接口作为参数
最佳实践
1.每个类尽量都有接口或者抽象类
2.变量的表面类型(声明类型)尽量是接口或者抽象类
3.任何类都不应该从具体类派生
4.尽量不要覆写基类方法
5.结合里氏替换原则使用
倒置源于正置,正置就是正常人的思维,开车就依赖车,编程中需要抽象,产生的抽象类和接口,根据系统需求产生了抽象间的依赖,不是传统思维的依赖。
接口隔离原则
接口
实例接口:java类就是一种接口
类接口:Interface
隔离
1.依赖需要的接口
2.类间依赖关系应该建立在最小的接口上
迪米特法则
一个类应该对耦合类知道的越少越好的
原则:如果一个方法放在本类中,即不增加类间关系,也对本类不产生负面影响,就放在本类中
六度分隔理论
开闭原则

Maven安装最佳实践

设置MAVEN_OPTS环境变量

前面介绍Maven安装目录时我们了解到,运行mvn命令实际上是执行了Java命令,既然是运行Java,那么运行Java命令可用的参数当然也应该在运行mvn命令时可用。这个时候,MAVEN_OPTS环境变量就能派上用场。

通常需要设置MAVEN_OPTS的值为-Xms128m -Xmx512m,因为Java默认的最大可用内存往往不能够满足Maven运行的需要,比如在项目较大时,使用Maven生成项目站点需要占用大量的内 存,如果没有该配置,则很容易得到java.lang.OutOfMemeoryError。因此,一开始就配置该变量是推荐的做法。

关于如何设置环境变量,请参考前面设置M2_HOME环境变量的做法,尽量不要直接修改mvn.bat或者mvn这两个Maven执行脚本文件。因 为如果修改了脚本文件,升级Maven时就不得不再次修改,一来麻烦,二来容易忘记。同理,应该尽可能地不去修改任何Maven安装目录下的文件。

 

mvn compiler:compile时出现非法字符: /65279错误

原因:

UltraEdit、EditPlus等编辑器会在utf8编码格式的文件开头添加utf8标识,使文件的编码格式由utf8变为utf8+BOM,导致maven编译时将utf8标识误认为非法字符。

解决办法:

通过UltraEdit、EditPlus等编辑器将utf8+BOM编码格式的文件改为utf8格式,去掉文件开头的utf8标识即可。

 

maven中如何忽略单元测试中的错误继续构建工程

maven中默认的情况下如果单元测试有错误,将会停止构建工程,如果想忽略错误而继续构建的话只需在pom.xml文件中添加下面的配置即可:

 

<project> [...] <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <testFailureIgnore>true</testFailureIgnore> </configuration> </plugin> </plugins> </build> [...] </project>
这段配置将会忽略单元测试的错误而继续构建。
命令行:$ mvn test -Dmaven.test.failure.ignore=true

 

再见,光华

在走廊看到打电话的同学,忽然想起了海涛兄弟,那天捐款,他捐了100,等我要下楼的时候,他喊住我,又给我一百,我问为啥,他说:“我刚和对象打完电话,这是她要我替她捐的。“当时立刻羡慕起,真心希望以后能有机会参加海涛的婚礼,就要离开伴我四年的光华楼了,四年的生活的一些细节也会不时回想起来。

再见,光华!

碎碎念——距离开学还有不到一周的时间了

暑假过得比我想象中的要快很多,买的两本专业书没一本看完的,都看了一半

这几天忙活驾照晒得贼黑,宅了四年小胖子,一下回到军训后了

距离开学还有不到一周的时间了,研究生新生活就要开始了

刚刚在豆瓣看到了@某健的求交往的帖子,笑得不行了

想打个电话招人聊聊天,却没人接,算了

碎碎念结束,继续看书吧…

Java常用集合包适用场景

1. ArrayList

基于数组方式实现,无容量的限制。

在执行插入元素时可能要扩容,在删除元素时并不会减少数组的容量。

如果希望相应的缩小数组容量,可以调用trimToSize()

在查找元素时要遍历数组,对于非null的元素采取equals的方式寻找。

非线程安全。

2. LinkedList

基于双向链表机制实现。

元素的插入、移动较快。

非线程安全。

3. Vector

基于Object数组的方式来实现的。

基于synchronized实现的线程安全的ArrayList。

在插入元素时容量扩充的机制和ArrayList稍有不同:
如果capcacityIncrement > 0, 则Object数组的大小扩大为现有size加上capcacityIncrement;
如果capcacityIncrement < 0, 则Object数组的大小扩大为现有size的两倍;

4. Stack

基于Vector实现,支持LIFO。

5. HashSet

基于HashMap实现,无容量限制。

不允许元素重复。

非线程安全。

6. TreeSet

基于TreeMap实现,支持排序。

非线程安全。

7. HashMap

采用数组方式存储key、value构成的Entry对象,无容量限制。

基于key hash寻找Entry对象存放到数组的位置,对于hash冲突采用链表的方式来解决。

在插入元素时可能会扩大数组的容量,在扩大容量时会重新计算hash,并复制对象到新的数组中。

非线程安全。

8. TreeMap

基于红黑树实现,无容量限制。

非线程安全。

———————————–
适用场景:

对于查找和删除较为频繁,且元素数量较多的应用,Set或Map是更好的选择;

ArrayList适用于通过为位置来读取元素的场景;

LinkedList 适用于要头尾操作或插入指定位置的场景;

Vector 适用于要线程安全的ArrayList的场景;

Stack 适用于线程安全的LIFO场景;

HashSet 适用于对排序没有要求的非重复元素的存放;

TreeSet 适用于要排序的非重复元素的存放;

HashMap 适用于大部分key-value的存取场景;

TreeMap 适用于需排序存放的key-value场景。