参考web的jsoncat框架,实现一个控制台IO的commandfast简易框架,并进行使用。
目录
程序效果
实现过程
样例代码
工程文件
参考资料
程序效果
截图1.查询当前时间和用户,查询磁盘空间
利用commandfast框架,实现的2个简单功能,界面显示出功能名称列表,输入对应名称即可使用相关功能。比如这里显示的“CurrentBaseInfo”、“CurrentDiskInfo”。
截图2-3.工程目录结构
开发只用关注在main所在类中调用框架入口方法run、基于框架“CommandFastPro”接口定义Controller类,Controller还需要调用其他类的,利用@Service定义类并使用@Autowired注入到Controller中。
实现过程
1.开发应用视角
截图2.使用commandfast的开发过程
不需要在开发过程中new自定义的类,交给框架来管理。
只需要:
步骤一、使用@Component注解修饰main所在类,告诉commandfast应用所在的jar包名称。
步骤二、使用@Controller注解修饰功能入口所在类,Controller类需要继承commandfast中定义的“CommandFastPro”接口(需要实现一个work方法作为入口)。
步骤三、使用@Service注解修饰@Controller的类调用的类,并使用@Autowired注解在Controller类中注入。
步骤四、编译、运行应用即可。
2.框架启动流程视角
截图3.启动流程
开发过程只用关注业务实现的代价是,commandfast框架部分需要操心很多。
其中包括
(1)与用户的交互:规定参数格式,本次示例没有使用args入参,只使用了Controller实例名用于调用对应的bean。
(2)类扫描:要扫描用户定义类的包里面所有@Controller、@Service描述的类。
(3)类的实例化及注入:将扫描出的每个类生成实例,涉及@Autowired注入的属性,需要将Service的实例设置进去,否则会报空指针异常。
样例代码
1.应用开发视角
(1)main方法
package maplegam.com.application;
@ComponentScan(name = "maplegam.com.application")
public class CommandApp {
public static void main(String[] args) throws IOException {
CommandFastApplication.run(CommandApp.class, args);
}
}
(2)定义Controller类
@Controller(name = "CurrentDiskInfo")
public class CurrentDiskInfo implements CommandFastPro {
@Autowired
MemDisk memDisk;
public void work() {
memDisk.getDiskInfo();
memDisk.getMemInfo();
}
}
@Controller注解中的name会存放于BeanFactory中,用户输入名称,也是通过这个找到对应的bean。
@Autowired修饰的类不需要实例化,由框架注入。
(3)定义Service类
@Service
public class MemDisk {
public static void getDiskInfo() {
File[] disks = File.listRoots();
System.out.println("[DiskInfo]");
for(File file : disks) {
System.out.print(file.getPath() + " ");
System.out.print("total = " + file.getTotalSpace() / 1024 / 1024 + "M," + " ");// 总空间
System.out.print("unuse = " + file.getFreeSpace() / 1024 / 1024 + "M," + " ");// 空闲空间
System.out.print("already used = " + file.getUsableSpace() / 1024 / 1024 + "M");// 可用空间
System.out.println();
}
}
public static void getMemInfo() {
System.out.println("[MemInfo]");
OperatingSystemMXBean mem = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
System.out.println("Total RAM:" + mem.getTotalPhysicalMemorySize() / 1024 / 1024 + "MB");
System.out.println("Available RAM:" + mem.getFreePhysicalMemorySize() / 1024 / 1024 + "MB");
}
}
该Service类的实例会被注入到(2)中的Controller中。
一个功能的开发只用涉及(1)、(2)、(3),如果Controller功能简单不用调用其他类,那么(3)都不用开发。
2.框架视角
(1)run方法
public class CommandFastApplication {
public static void run(Class<?> mainClass, String[] args) throws IOException {
System.out.println("CommandFastApplication is starting!");
//获取注解里面的信息
ComponentScan componentScan = mainClass.getAnnotation(ComponentScan.class);
String packageName = componentScan.name();
System.out.println("package name:"+packageName);
//根据@ComponentScan里的包名进行扫描
String[] packageNames = new String[]{packageName};
ClassFactory.loadClass(packageNames); //加载用户开发的类
BeanFactory.loadBeans(); //将类生成实例
DependencyInjection.inject(); //实例中@Autowire的属性进行注入
System.out.println("CommandFastApplication is running!");
//控制台输入输出界面
ProvideService.start();
}
}
(2)控制台IO相关类
public class ProvideService {
public static void start() throws IOException {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s = null;
while (true) {
System.out.println("Please input a service name to work:");
ClassFactory.CLASSES.get(Controller.class).forEach(aClass -> {
String beanName = BeanHelper.getBeanName(aClass);
System.out.println(beanName);
});
s=br.readLine();
s.trim();
//从BEAN中获取同名实例,强制类型转换成接口“CommandFastPro”类型,调用work入口方法
if (BeanFactory.BEANS.get(s) != null) {
CommandFastPro commandFastPro = (CommandFastPro) BeanFactory.BEANS.get(s);
commandFastPro.work();
}
System.out.println();
}
}
}
(3)被应用使用的注释和接口
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ComponentScan {
String name() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
String name() default "";
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
}
public interface CommandFastPro {
public void work();
}
run方法中的几个方法涉及的代码不详细贴,主要涉及:
Reflection工具类(导入reflections-0.9.12.jar),可使用其中的包扫描功能,及其他反射相关方法。
工程文件
1.下载地址:
https://pan.baidu.com/s/1sAUSHeL5zjlUh7Lp5y9EKw
2.提取码:x7p8
参考资料
1.jsoncat源码及相关教程
微信公众号“JavaGuide”作者写的jsoncat框架,框架教程在公众号里有。
源代码:https://github.com/Snailclimb/jsoncat