龙空技术网

重要Java规范拾遗

iMinusMinus 51

前言:

当前我们对“js object对象”都比较珍视,大家都想要剖析一些“js object对象”的相关资讯。那么小编也在网上网罗了一些有关“js object对象””的相关文章,希望看官们能喜欢,同学们一起来学习一下吧!

JCache

JCache

spring-context

备注

缓存key

javax.cache.annotation.CacheKey

org.springframework.cache.annotation.Cache*(key=)

spring-cache的CacheKey支持SpEL

缓存无则执行

javax.cache.annotation.CacheResult

org.springframework.cache.annotation.Cacheable

JCache允许不检查缓存总是执行,spring-cache支持避免多线程同时加载相同key

执行后缓存

javax.cache.annotation.CachePut

javax.cache.annotation.CacheValue

org.springframework.cache.annotation.CachePut

JCache默认将非CacheValue标记的参数作为CacheKey

移除单个key

javax.cache.annotation.CacheRemove

org.springframework.cache.annotation.CacheEvict

JCache/spring-cache可以选择执行前移除缓存

缓存移除

javax.cache.annotation.CacheRemoveAll

org.springframework.cache.annotation.CacheEvict(allEntries=true)

异常处理

javax.cache.annotation.Cache*(cacheFor={}, noCacheFor={})

org.springframework.cache.annotation.Cache*(condition=, unless=)

缓存配置

javax.cache.annotation.CacheDefaults

org.springframework.cache.annotation.CacheConfig

JCache/spring-cache支持在类上配置cacheName、CacheResolver、CacheKeyGenerator

从注解和接口设计来看,JCache和spring-cache十分相似,都支持类级别配置缓存的cacheName、CacheResolver、CacheKeyGenerator,也允许在方法级别上进行覆盖。

在方法级别的注解上,都支持特定条件去取/存/清除缓存。但方式上有区别,体现在spring-cache以容器为核心,CacheResolver、CacheKeyGenerator这种配置都是配置容器内的bean id,对于条件的处理则是依赖SpEL的支持。 而JCache设计时并没有过多的考虑接纳DI/CDI,在条件上则仅考虑异常来二分。 值得注意的是,JCache在扩展性上考虑到了缓存创建、更新、失效、移除的事件监听。 此外,JCache虽不能直接配置每个key的失效策略,但有API(javax.cache.expiry.ExpiryPolicy)来规范这些行为。

spring-cache也实现了JCache,底层支持的本地缓存可以是caffeine、cache2k、Guava cache、ehcache,分布式缓存可以是Infinispan、Hazelcast、Couchbase、 Redis等。

JMX

JMX即Java Management Extensions,属于Java SE平台的一部分,它提供了一个简单、标准的监控、管理JVM和应用程序的方式。

JMX规范定义了5种类型的MBean:Standard MBeans为实现类与接口类名称遵循一定格式(接口类名形如NameMBean,实现类则为Name),接口定义可读写的属性和可调用的操作; MXBeans与Standard MBeans类似,不同之处在于接口后缀为MXBean,或使用MXBean注解标记时可以不需要此后缀; Dynamic MBeans定义了DynamicMBean作为通用的动态MBean接口,实现类可以有选择的暴露属性和操作(甚至可以是类并不存在的属性或方法),而其他私有和公有方法或字段对JMX体系不可见; Model MBeans也是一种Dynamic MBeans,它可以桥接管理接口和托管资源,特殊之处在于它支持持久化、通知、属性值缓存、操作代理; Open MBeans也是一种Dynamic MBeans,特殊之处在于它通过一系列预定义的java类(如包装类、TabularData、CompositeData)来支持非java程序的远程管理端。

JMX

micrometer

dropwizard-metrics

备注

协议

RMI

http

-

JMX的connector有RMI,adapter可以是SNMP

指标类型

-

Meter: Gauge, Counter, Timer, DistributionSummary, LongTaskTimer, FunctionCounter, FunctionTimer, TimeGauge

Metric: Gauges, Counters, Meter, Histograms, Timers

JMX内建资源分类

监控对象处理

-

io.micrometer.core.instrument.config.MeterFilter

com.codahale.metrics.MetricFilter

模式

push

push

push

registry/agent

javax.management.MBeanServer

io.micrometer.core.instrument.MeterRegistry

com.codahale.metrics.MetricRegistry

micrometer可以同时注册到JMX、prometheus、atlas、graphite等;dropwizard支持graphite、jmx、http等

监控面板

JConsole

-

console, SLF4J, CSV

标记为指标信息提供者

javax.management.MXBean

io.micrometer.core.annotation.Counted

io.micrometer.core.annotation.Timed

-

spring-boot-actuator提供了Endpoint来标记对象id(或访问路径)

标记属性读写、行为

javax.management.DynamicMBean.getAttribute

javax.management.DynamicMBean.setAttribute

javax.management.DynamicMBean.invoke

-

-

spring-boot-actuator提供了ReadOperation、WriteOperation、DeleteOperation来读写属性

可以看到各种度量框架一般会分为当前值(Gauges)、累计值(Counters)、耗时(Timer)。 JMX定义了类似的GaugeMonitor、CounterMonitor和StringMonitor,支持统计值超出阈值范围时发出通知。

micrometer作为监控界相当于日志界SLFJ的门面框架,支持多种数据采集/存储工具,还定义了DistributionSummary(带次数和累计信息)、LongTaskTimer(记录长时间任务的执行任务数、持续时间)、TimeGauge(有单位的瞬时值)。 micrometer提供的Counted、Timed注解,在spring框架下通过AOP来发生效应。

dropwizard-metrics还定义了Meter(累计值和均值,如最近1分钟、5分钟、15分钟均值)、Histograms(累计值和近期多个瞬时值)。

spring-boot-actuator可以使用JMX形式或HTTP端点形式管理和监控应用程序,它还支持采集和输出指标、审计、http链路跟踪、健康探测(提供了就绪检查、存活检查,可以很好的与Kubernetes结合)。 spring-boot-actuator支持对Jolokia(一个JMX-HTTP桥接框架)、micrometer进行开箱即用。 spring-boot-actuator与JMX都提供了读、写属性的能力,JMX还提供了操作的能力,但spring为JMX端点和http端点提供了一个统一的门面。

JMX不只可以做监控(读取属性),也可以管理(修改属性,执行操作,产生通知)。

JPMS

Jigsaw项目的产物为JPMS(Java Platform Module System),在JDK9及以上版本内置。

JPMS

OSGi

备注

模块依赖

module-info.java: requires

MANIFEST.MF: Import-Package

依赖透明传递

module-info.java: requires transitive

不支持

依赖多版本共存

不支持

支持

OSGi中每个bundle有自己的类加载器

依赖分类

不支持

不支持

maven分为compile, runtime, test, provided; optional

限定导出

module-info.java: exports

MANIFEST.MF: Export-Package

JPMS有如下几个好处:

rt.jar变成了多个jmod,方便裁剪JRE,缩小云原生镜像打包体积通过module-info.java的opens和exports语法,可以约束外部使用者(当然也会受依赖的模块约束)得益于module-info.java的opens语法,JVM可以加快搜索类的速度由于module-info.java的requires语法,同类名在不同模块的冲突可以得到解决

要享受到JPMS的好处,先需要进行改造。

如果对应到Maven上,简单地说就是一个maven模块一个module-info.java文件, 而且module-info.java文件必须在源代码根目录下,一般是"src/main/java"目录下。

以下是一个module-info.java的示例及说明:

/* open */ // 模块下所有包都开放module module.name { // 命名规则和包名类似,建议使用符合命名要求的Maven artifactId或java package   requires java.base; // 依赖的模块名   requires transitive org.slf4j; // 依赖本模块的模块,无需再声明依赖org.slf4j模块   requires static option.al; // 编译期需要的依赖,运行时可选   requires org.slf4j; // 对于尚未模块化(unnamed module)的依赖,JPMS从模块定义中无法加载时,回退到classpath进行加载      exports p.a.c.k.a.g.e; // 允许所有模块访问指定package   exports pack.age to other.pack.age, another.pack.age; // 仅允许指定模块访问指定package      opens module.name.sub; // 允许"module.name.sub"包运行时被访问(即反射)   opens module.name.child to p.k.g, pack.age; // 仅允许指定包      uses s.p.i; // 模块需要使用到SPI的实现      provides s.p.i with c.l.a.s.s; // 声明模块的类实现的SPI}

模块化后,也会带来坏处,主要是兼容上的影响:

ClassLoader::getResource*, Class::getResource*对于JDK内部资源,无法再通过类加载形式获取。模块私有资源被限制在模块内,需要改用Module::getResourceAsStream形式,或者使用"jrt:"格式。META-INF/servicesSPI实现已经在module-info.java声明了,旧形式可免除。AccessibleObject::setAccessible模块化前可以通过setAccessible来访问方法或字段,现在必须先开放给访问包。URLClassLoadersun.misc.Launcher.AppClassLoader和sun.misc.Launcher.ExtClassLoader被移除, 取而代之的jdk.internal.loader.ClassLoaders.AppClassLoader、jdk.internal.loader.ClassLoaders.PlatformClassLoader并不是URLClassLoader的子类。

常见问题:

unit test通常单元测试会引入JUnit、Mockito一类的框架,在Maven中会被声明scope为test,即正式打包时不会包含单元测试框架。 而模块化后,我们的module-info.java自然不会包含junit等测试依赖包。而如果不将依赖引入,单元测试又会运行失败。解决办法是在测试目录("src/test/java")下添加module-info.java,复制正式模块文件内容,修改模块名称,并引入单元测试所需依赖。自动模块包引用冲突如果从多个自动模块(即JDK9前没有module-info.java的jar被JDK自动以jar名称来生成模块名)读取相同的包,则会发生包冲突(但p.k.g.a和p.k.g.b不会冲突)。此时,只能等库作者要么将多个库进行合并,或者将库使用不同的包名。

标签: #js object对象