软件工程师,特别是开发客户端产品,App这一类,都免不了需要判断当前所处环境。比如客户端产品要判断是Windows/Linux系统,x86还是x64等等。 App则需要判断安卓、iOS的版本,当前环境是否WIFI之类的。
创新互联是专业的沙洋网站建设公司,沙洋接单;提供成都网站设计、成都网站制作,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行沙洋网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!
对于 Java 应用, 无论 Web 还是 桌面应用,也会遇到需要判断当前所使用的 JDK 版本,当前应用对应的操作系统等等。
比如我们在几年前做应用服务器集群管理与监控时,需要判断应用服务器所属物理机器的CPU以及内存的使用率、对于服务器实例进行操作,对于不同的JVM 实现,采用不同的attach机制等等。当时是使用 Sigar 进行这些硬件信息的获取。
由于提供的是All in One 的版本,所以需要判断操作系统类型,来判断加载 Sigar 的Windows支持 dll 文件还是Linux 支持 so 文件。
当然获取操作系统类型、版本都较容易,直接通过System 的getProperty再加上对应的名称就能拿到,比如「os.name」,「os.arch」等。对于 JVM 的厂商,则可以通过「java.vm.vendor」来得到,完整的可以通过System.getProperties全部拿到。
如果习惯使用JMX 读取Platform 的 MBean,也可以通过 JMX来获取,便捷操作类似这样:
- OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
- System.out.println(os.getName());
本质上也都是一样的。
那除了这种方式,还有哪些方式可以获取到呢?一般开源软件又是怎么做的呢?
我们来看 Tomcat 内部怎么实现的。
我们发现, Tomcat 内部,对于通过 System 的 properties获取到的,基本都是用来打印 Log 和输出使用,对于应用内的控制,基本没看到使用。
那 Tomcat在判断版本时,是怎么做的呢?为什么不直接用这个呢?
首先看怎么做的。
前面的文章提到过, Tomcat 对于内存泄漏做了一些努力,比如先Hold 一块内存这种(Tomcat与内存泄露处理),也比如防止内存泄漏的PreventionListener,会先将可能共用的 class加载到Common classLoader里。
那这里加载到 Common classLoader这些常用 class时,就需要判断当前是Java 哪个版本,因为有些 class 是某些版之后才出现的。
具体实现是这个样子:
- // Trigger a call to sun.awt.AppContext.getAppContext(). This
- // will pin the system class loader in memory but that shouldn't
- // be an issue.
- if (appContextProtection && !JreCompat.isJre8Available()) {
- ImageIO.getCacheDirectory();
- }
- // Trigger the creation of the AWT (AWT-Windows, AWT-XAWT,
- // etc.) thread
- if (awtThreadProtection && !JreCompat.isJre9Available()) {
- java.awt.Toolkit.getDefaultToolkit();
- }
什么时候 Available了?
- static {
- // This is Tomcat 8 with a minimum Java version of Java 7. The latest
- // Java version the optional features require is Java 9.
- // Look for the highest supported JVM first
- if (Jre9Compat.isSupported()) {
- instance = new Jre9Compat();
- jre9Available = true;
- jre8Available = true;
- }
- else if (Jre8Compat.isSupported()) {
- instance = new Jre8Compat();
- jre9Available = false;
- jre8Available = true;
- } else {
- instance = new JreCompat();
- jre9Available = false;
- jre8Available = false;
- }
- }
具体是不是支持是直接通过加载特定版JDK 对应的 class 来判断
- static {
- Method m1 = null;
- try {
- // The class is Java6+...
- Class> c1 = Class.forName("javax.net.ssl.SSLParameters");
- // ...but this method is Java8+
- m1 = c1.getMethod("setUseCipherSuitesOrder", boolean.class);
- } catch (SecurityException e) {
- // Should never happen
- } catch (NoSuchMethodException e) {
- // Expected on Java < 8
- } catch (ClassNotFoundException e) {
- // Should never happen
- }
- setUseCipherSuitesOrderMethod = m1;
- }
通过这种加载 class 的方式,和 我们前面通过 System.property获取,有啥区别呢?
要知道, System 的 Property 是个系统属性,是可配置的,也就是说,谁都可以进行setProperty的操作。如果不巧被别人改了,那你的程序可能就会出现不符合你预期的行为。
而加载类的形式,并不受其他人的影响。是最真实的一线声音。
这样的判断不方式,不仅 Tomcat 自己,其他框架也有在用。我们来看 Spring Boot。
Boot 执行的时候,有时候会判断当前应用是否需要支持 Web, 类似于是否加载了 Spring MVC 这种。
- private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
- "org.springframework.web.context.ConfigurableWebApplicationContext" };
- private boolean deduceWebEnvironment() {
- for (String className : WEB_ENVIRONMENT_CLASSES) {
- if (!ClassUtils.isPresent(className, null)) {
- return false;
- }
- }
- return true;
- }
然后在启动时候,会调用deduceWebEnvironment 方法,从而决定一些执行的逻辑。
还有其他方式么? 如何不想自己手工处理,可以使用一些工具类,比如 Apache 的 commons-lang, 提供了一个 SystemUtils 可以直接。例如判断操作系统和 Java 版本
- if (SystemUtils.IS_JAVA_1_7) {
- System.out.println("Hello 1.7");
- }
工具类是怎么做的呢?
- public static final String JAVA_VERSION = getSystemProperty("java.version");
- private static String getJavaVersionTrimmed() {
- if(JAVA_VERSION != null) {
- for(int i = 0; i < JAVA_VERSION.length(); ++i) {
- char ch = JAVA_VERSION.charAt(i);
- if(ch >= 48 && ch <= 57) {
- return JAVA_VERSION.substring(i);
- }
- }
- }
- return null;
- }
说到底,也还是System.getProperty.
所以,在检测环境的时候,我们可以通过System.getProperty,也可以通过 Tomcat 和 Spring 这种加载 class 的方式。或者干脆直接用工具类。 你还用过啥办法呢?
【本文为专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】
本文题目:谈谈如何在运行时获取「环境」信息
转载来于:http://www.shufengxianlan.com/qtweb/news37/553287.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联