首页 资讯 精华 论坛 问答 博客 专栏 组 更多 ▼
招聘 搜索 您还未登录 ! 登录 注册 whitesock博客微博相册收藏留言关于我  .JLine 博客分类: SE
JLine .
Overview
JLine 是一个用来处理控制台输入的Java类库,目前最新的版本是0.9.94。其官方网址是jline.sourceforge。在介绍JLine之前,首先还是介绍一下Java 6中的Console类,以便进行对比。
2 Java Console
通过调用sole()方法可以得到与当前虚拟机对应的Console对象。但是该方法并不保证其返回值一定非null,这取决于底层平台和虚拟机启动的方式:如果是通过交互式的命令行启动,并且标准输入和输出流没有被重定向,那么该方法的返回值通常是非null;如果是被自动启动(例如cron)或者通过Eclipse启动,那么返回值通常为null。
Console类支持的功能有限,其中一个比较有用的功能是以非回显(echo)的方式从控制台读取密码。
3 JLine
JLine不依赖任何core Java以外的类库,但是其不是纯Java的实现。
?在Windows平台下,JLine通过自带的.dll文件初始化终端。jline.jar中包含了jline32.dll和jline64.dll,在Windows平台上使用的时候, JLine会自动将其解压缩到临时目录并进行加载。
?在Unix或者Max OS X平台下,JLine通过stty命令初始化终端。例如通过调用stty -icanon min 1将控制台设置为character-buffered模式。以及通过调用stty -echo禁止控制台回显。在修改终端的属性之前,JLine会对终端的属性进行备份,然后注册一个ShutdownHook,以便在程序退出时进行恢复。由于JVM在非正常退出时(例如收到SIGKILL信号)不保证ShutdownHook一定会被调用,因此终端的属性可能无法恢复。
JLine使用起来非常简单,jline.jar中一共只有20几个类,源码也不难懂。以下是个简单的例子,其中readLine函数的参数指定了命令行提示符:
Java代码 
1.ConsoleReader reader = new ConsoleReader(); 
2.String line = adLine(">"); 
ConsoleReader reader = new ConsoleReader();
String line = adLine(">"); 
3.1 Features
3.1.1 Command History
通过按下键盘的上下箭头键,可以浏览输入的历史数据。此外JLine也支持终端快捷键,例如Ctrl+A, Ctrl+W,Ctrl+K, Ctrl+L等等,使用的时候非常便捷。
可以通过ConsoleReader的setUseHistory(boolean useHistory)方法启用/禁用Command History功能。ConsoleReader的history成员变量负责保存历史数据,默认情况下历史数据只保存在内存中。如果希望将历史数据保存到文件中,那么只需要以File对象作为参数构造History对象,并将该History对象设置到ConsoleReader即可。
3.1.2 Character Masking
ConsoleReader提供了一个readLine(final Character mask)
方法,用来指定character mask。如果参数为null,那么输入的字符正常回显;如果为0,那么不回显;否则回显mask指定的字符。
3.1.3 Tab Completion
JLine中跟自动补全相关的接口是Completor,它有以下几个实现:
?SimpleCompletor: 对一系列指定的字符串进行自动补全。
?FileNameCompletor: 类似于bash中的文件名自动补全。
?ClassNameCompletor: 对classpath中出现的全路径类名进自动补全。
?NullCompletor: 不进行自动补全。
?ArgumentCompletor: 为每个属性使用指定的Completor。
以下是个简单的例子:
Java代码 
1.ConsoleReader reader = new ConsoleReader(); 
2.List<Completor> completors = new ArrayList<Completor>(); 
3pletors.add(new SimpleCompletor(new String[]{"abc", "def"})); 
4pletors.add(new FileNameCompletor()); 
5pletors.add(new ClassNameCompletor()); 
6pletors.add(new NullCompletor()); 
ConsoleReader reader = new ConsoleReader();
List<Completor> completors = new ArrayList<Completor>();
completors.add(new SimpleCompletor(new String[]{"abc", "def"}));
completors.add(new FileNameCompletor());
completors.add(new ClassNameCompletor());
completors.add(new NullCompletor());
reader.addCompletor(new ArgumentCompletor(completors));
3.1.4 Custom Keybindings
通过创建 HOME/.jlinebindings.properties文件(或者制定 jline.keybindings 系统变量),可以定制keybindings。
4 Known Issues
JLine最知名的问题莫过于在Windows平台下的Eclipse中启动的程序中调用adLine()方法时总是
返回null(正确的行为是等待用户输入)。通过debug, 笔者发现通过设置jline.WindowsTerminal.directConsole属性为false,可以解决返回null的问题,但是感觉还是有些其它的问题。总之,笔者没有发现好的对策,只能work around,即对JLine再进行一层封装,在某些场景下仍然使用原始的基于System.in的流处理。
5 Usage
想必很多项目都会为其应用做一层Application之类的抽象。对应用进行监控的常见方式是使用JMX,JMX从逻辑上可以认为是应用程序的一个Shell。笔者为项目中的Application提供了一套完整的Shell抽象,包括Shell、Conso
le、 Process 和 Command等等。其中JLine是一种Console的具体实现。如果是后台应用,那么可以通过基于Socket的Console连接到应用,从而进行监控,例如停止应用程序等。如果前台的交互式应用,那么可以直接使用基于终端的Console实现, 例如笔者项目中为Spring Batch实现的CommandLine Scheduler等。
8
顶4
踩.分享到:  .Open Addressing | ID Generator 2010-06-17 09:11浏览 1914评论(2)分类:编程语言相关推荐评论
2 楼 whitesock 2010-06-18 
在读取命令行输入,并且需要类似bash等shell的命令行自动补全,命令历史,快捷键等特性时,可以考虑使用JLine。
1 楼 langyu 2010-06-18 
没发现有什么大的用途,楼主怎么解释下么发表评论
您还没有登录,请您登录后再发表评论
whitesock
浏览: 214977 次
性别:
来自: 大连
最近访客 更多访客>>
wangwei3lostyaozrhduduchinalg.文章分类
■全部博客 (91)
■ME (4)
■SE (35)
■EE (22)
■Perl (2)
■Lua (1)
■Scala (2)
■Python (2)
■Linux (5)
■MySQL (7)
■Spring (4)
■Concurrent (13)
■Miscellaneous (9)
社区版块
■我的资讯 (1)
■我的论坛 (79)
■我的问答 (2)
存档分类
■2012-02 (1)
■2012-01 (5)
■2011-12 (3)
■更多存档...
评论排行榜
■MySQL Open Replicator
■Inside AbstractQueuedSynchronizer (2)
■Nothing, Null, Nil, None & Unit in Scala
■Code Optimization
■Inside AbstractQueuedSynchronizer (3)
最新评论
wangwei3: 请问,如何将所接收的event按transaction划分? ...
MySQL Open Replicator
childz: 非常不错,感谢
What's New on Java 7 Phaser
huiding114: 在RBR模式下,如何能取到列名 和值能一对一配对的。我是想在 ...
MySQL Open Replicator
whitesock: 你配置的不正确,MySQL没有mysql_bin.000033 ...
MySQL Open Replicator
huiding114: 运地的时候报这个错 Exception in thread & ...
MySQL Open Replicator
.
] .
Spring小例子,看不懂你我。
第一步:打开myeclipse,建个web工程,名字叫spring_test
第二步:添加jar包
右击工程名,myeclipse –》add spring。。。
选择默认的 core包就行了。
注意:如果以上操作步骤完成,你的src下没有l,说名你的环境没搭好,重新建个项目,重复以上2步骤。
如果src 目录下有l 文件,那下面就开始写代码了:
首先建三个包
1. org. interfaces
2. org. interfaces.impl
3. st
4. 在org. interfaces 写2个接口
package org.interfaces;
public interface Food {
public String eat();
}
package org.interfaces;
public interface Person {
public void eatFood();
}
在org. interfaces.impl这里写实现的类
package org.interfaces.impl;
import org.interfaces.Food;
public class Apple implements Food {
public String eat() {
return "正在吃
苹果。。。";
}
}
package org.interfaces.impl;
import org.interfaces.Food;
import org.interfaces.Person;
public class Man implements Person {
private Food food;
public Food getFood() {
return food;
}
public void setFood(Food food) {
this.food = food;
}
public void eatFood() {
System.out.println(food.eat());
}
}
package org.interfaces.impl;
import org.interfaces.Food;
public class Orange implements Food {
public String eat() {
return "正在吃orange。。。";
}
}
在st包里写测试类
package org.interfaces.impl;
import org.interfaces.Person;
import t.ApplicationContext;
import t.support.ClassPathXmlApplicationContext;
import t.support.FileSystemXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//当l在src下时间使用
//ApplicationContext context =  new ClassPathXmlApplicationContext("l");
//  Person p =(Bean("man");
//    p.eatFood();
//在指定路径上l
ApplicationContext context = new FileSystemXmlApplicationContext("/WebRoot/l");
Person p =(Bean("man");
p.eatFood();
}
}
学习的道路上总会遇到空难,希望看我的小例子,能使你对spring有初步的认识。
上面的例子是我自己写的在配置文件里配注入方式。
Spring 实例入门
本文结合实例理解解容器,DI,IOC,耦合,解耦等Spring所涉及的概念,同时了解Spring的最基本也是最核心的使用方法。
1. Spring容器
Spring容器负责对象的实例化,对象生命周期的管理,被Spring管理的对象称之为Bean。
例如有Soldier类需要交由Spring容器管理,我们先编写类
package com.hb;
public class Soldier {
springframework作用private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
在Spring配置文件中添加如下配置
<bean id="s1" class="com.hb.Soldier"></bean>
初始化Spring容器
public class Test {
public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("l");
}
}
从Spring容器中取得对象实例
Soldier s1 = (Soldier) Bean("s1");
Spring默认使用单例的方式创建对象。可以通过修改<bean>的配置改变成其它创建方式。这个属性为Scope,称之为作用域或生命周期,它的值为singleton(单例,默认值),prototype(每次产生一个新的实例)等。
<bean id="s1" class="com.hb.Soldier" scope="prototype"></bean>
2. 注入方式有setter注入,构造注入方式,接口注入(不需掌握)。建议多使用Setter注入方式。
Setter注入:
Soldier类中有一个
属性name,如何在创建Soldier的时候使name的值变为”RANBO”?
配置如下:
<bean  id="s1"  class="com.hb.Soldier">
<property  name="name"  value="RANBO"/>
</bean>
这样创建的Soldier对象的name属性就有值了,测试代码:
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("l");
Soldier s1 = (Soldier) Bean("s1");
System.out.Name());
}
构造注入:
我们先修改下Soldier类,给它添加一个构造方法:
package com.hb;
public class Soldier {
private String name;
public Soldier(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
配置如下:
<bean  id="s1"  class="com.hb.Soldier">
<constructor-arg  value="RANBO"></constructor-arg>
</bean>
测试结果同上。
3. 依赖
当A对象使用了B对象的方法,A对B产生依赖,称之为A依赖B。下面的例子中Soldier类依赖HandGun类。
package com.hb;
/**
* 士兵类
*/
public class Soldier {
/**
* 打仗
*/
public void fight(){
HandGun handGun = new HandGun();
handGun.killEnemy();
}
}
package com.hb;
/**
* 手类
*/
public class HandGun {
/**
* 手杀敌
*/
public void killEnemy(){
System.out.println("手杀敌");
}
}
当HandGun发生变化时,必然导致Soldier必须做相应修改,同时,当Soldier需要使用OtherGun时也必须重新编写代码,导致代码重用度不高。
当对象之间的依赖关系很强时(耦合),会使程序代码死板,不利于后期的维护和扩展。降低对象之间的依赖关系称之为解耦。Spring能够很好的解决这一问题。
4. 控制反转(Inversion of Control,简称IOC)和依赖注入(Dependence Inject简称DI)
我们运用Spring的setter注入方式解决HandGun和Soldier的耦合问题。修改Soldier的代码,将HandGun定义为Soldier的属性并提供setter方法:
package com.hb;
/**
* 士兵类
*/
public class Soldier {
private HandGun handGun;
public void setHandGun(HandGun handGun) {
this.handGun = handGun;
}
/**
* 打仗
*/
public void fight(){
handGun.killEnemy();
}
}
配置如下
<bean  id="s1" class="com.hb.Soldier">
<property name="handGun">
<ref bean="handgun"></ref>
</property>
</bean>
<bean id="handgun" class="com.hb.HandGun"></bean>
到这里,我们已经降低了HandGun和Soldier的部分依赖关系,至少在Soldier中不用再自己去实例化Han
dGun了。然而并没有彻底解决问题,Soldier中仍然可以看到HandGun类,因此我们使用接口进一步改进代码:
package com.hb;
/**
* 武器接口
*/
public interface Weapon {
/**
* 杀敌
*/
void killEnemy();
}
package com.hb;
/**
* 手类
*/
public class HandGun implements Weapon{
/**
* 手杀敌
*/
public void killEnemy(){
System.out.println("手
杀敌");
}
}
package com.hb;
/**
* 士兵类
*/
public class Soldier {
private Weapon weapon;
public void setWeapon(Weapon weapon) {
this.weapon = weapon;
}
/
**
* 使用武器打仗
*/
public void fight(){
weapon.killEnemy();
}
}
配置如下
<bean id="s1" class="com.hb.Soldier">
<property name="weapon">
<ref bean="handgun"></ref>
</property>
</bean>
<bean id="handgun" class="com.hb.HandGun"></bean>
测试:
ApplicationContext context = new
ClassPathXmlApplicationContext("l");
Soldier s1 = (Soldier) Bean("s1");
s1.fight();
至此,我们使用Spring很好的解决了HandGun和Soldier的耦合问题。Soldier类中再也看不到HandGun的踪影了,Soldier只依赖于接口,而最终Soldier还是使用了HandGun,这是为什么呢?Spring在这里管理了单个的对象,也管理了对象之间即Soldier和HandGun的依赖关系。原本是由Soldier控制HandGun的实例化的,转变为由Spring容器来控制,这里发生了控制权的转移,这就是控制反转(Inversion of C
ontrol,简称IOC)。当Soldier需要HandGun时,Spring会自动将HandGun对象注入给Soldier,这就是依赖注入了。
看一下你是否已经有所领悟了:
假如“手“已经不满足“士兵”的需要,我们需要将“手”更换为更先进的“机”,你的程序如何编写呢?自己试一下吧!!
spring2.0常见异常
2009-04-06 19:50:51|  分类: Spring |  标签: |字号大中小 订阅
1:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.springframework.util.ClassUtils.<clinit>(ClassUtils.java:67)  at io.DefaultResourceLoader.<init>(DefaultResourceLoader.java:52) at t.support.AbstractApplicationContext.<init>(AbstractApplicationContext.java:184) at t.support.AbstractRefreshableApplicationContext.<init>(AbstractRefreshableApplicationContext.java:80) at t.support.AbstractXml
ApplicationContext.<init>(AbstractXmlApplicationContext.java:58)  at
需要加上:commons-logging.jar log4j-1.2.11.jar
2:Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [l]; nested exception is java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
Caused by: java.lang.NoClassDefFoundError: org/aspectj/weaver/reflect/ReflectionWorld$ReflectionWorldException
at java.lang.Class.forName0(Native Method)
需要加上:aspectjweaver.jar
3:Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'logBean' defined in class path resource [l]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigE

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。