ehcache jsr 使用
ehcache 實作了jsr規範,除了通過原生api使用ehcache外,還可以使用jsr提供的相應接口使用ehcache
************************
導入 jar 包
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.1.1</version>
</dependency>
************************
相關類與接口
Caching
public final class Caching {
public static final String JAVAX_CACHE_CACHING_PROVIDER = "javax.cache.spi.CachingProvider";
private static final Caching.CachingProviderRegistry CACHING_PROVIDERS = new Caching.CachingProviderRegistry();
private Caching() {
}
public static ClassLoader getDefaultClassLoader() {
return CACHING_PROVIDERS.getDefaultClassLoader();
}
public static void setDefaultClassLoader(ClassLoader classLoader) {
CACHING_PROVIDERS.setDefaultClassLoader(classLoader);
}
**************
擷取CachingProvider
public static CachingProvider getCachingProvider() {
public static CachingProvider getCachingProvider(ClassLoader classLoader) {
public static CachingProvider getCachingProvider(String fullyQualifiedClassName) {
public static CachingProvider getCachingProvider(String fullyQualifiedClassName, ClassLoader classLoader) {
public static Iterable<CachingProvider> getCachingProviders() {
public static Iterable<CachingProvider> getCachingProviders(ClassLoader classLoader) {
**************
擷取cache
public static <K, V> Cache<K, V> getCache(String cacheName, Class<K> keyType, Class<V> valueType) {
return getCachingProvider().getCacheManager().getCache(cacheName, keyType, valueType);
}
**************
内部類:CachingProviderRegistry
private static class CachingProviderRegistry {
private WeakHashMap<ClassLoader, LinkedHashMap<String, CachingProvider>> cachingProviders = new WeakHashMap();
private volatile ClassLoader classLoader = null;
public CachingProviderRegistry() {
}
public ClassLoader getDefaultClassLoader() {
public void setDefaultClassLoader(ClassLoader classLoader) {
public CachingProvider getCachingProvider() {
public CachingProvider getCachingProvider(ClassLoader classLoader) {
public CachingProvider getCachingProvider(String fullyQualifiedClassName) {
public synchronized CachingProvider getCachingProvider(String fullyQualifiedClassName, ClassLoader classLoader) {
public Iterable<CachingProvider> getCachingProviders() {
public synchronized Iterable<CachingProvider> getCachingProviders(ClassLoader classLoader) {
protected CachingProvider loadCachingProvider(String fullyQualifiedClassName, ClassLoader classLoader) throws CacheException {
CachingProvider
public interface CachingProvider extends Closeable {
CacheManager getCacheManager();
CacheManager getCacheManager(URI var1, ClassLoader var2);
CacheManager getCacheManager(URI var1, ClassLoader var2, Properties var3);
URI getDefaultURI();
Properties getDefaultProperties();
ClassLoader getDefaultClassLoader();
void close();
void close(ClassLoader var1);
void close(URI var1, ClassLoader var2);
boolean isSupported(OptionalFeature var1);
}
EhcachingProvider
@Component
public class EhcacheCachingProvider implements CachingProvider {
private static final String DEFAULT_URI_STRING = "urn:X-ehcache:jsr107-default-config";
private static final URI URI_DEFAULT;
private final Map<ClassLoader, ConcurrentMap<URI, Eh107CacheManager>> cacheManagers = new WeakHashMap();
*********
構造方法
public EhcacheCachingProvider() {
}
*********
CacheManager操作
public CacheManager getCacheManager(URI uri, ClassLoader classLoader, Properties properties) {
public CacheManager getCacheManager(URI uri, Configuration config) {
public CacheManager getCacheManager(URI uri, Configuration config, Properties properties) {
public CacheManager getCacheManager(URI uri, ClassLoader classLoader) {
public CacheManager getCacheManager() {
Eh107CacheManager getCacheManager(EhcacheCachingProvider.ConfigSupplier configSupplier, Properties properties) {
private Eh107CacheManager createCacheManager(URI uri, Configuration config, Properties properties) {
*********
其餘操作
public ClassLoader getDefaultClassLoader() {
public URI getDefaultURI() {
public Properties getDefaultProperties() {
public void close() {
public void close(ClassLoader classLoader) {
public void close(URI uri, ClassLoader classLoader) {
void close(Eh107CacheManager cacheManager) {
public boolean isSupported(OptionalFeature optionalFeature) {
private static Properties cloneProperties(Properties properties) {
static {
try {
URI_DEFAULT = new URI("urn:X-ehcache:jsr107-default-config");
} catch (URISyntaxException var1) {
throw new CacheException(var1);
}
}
*********
内部類:ConfigSupplier
static class ConfigSupplier {
private final URI uri;
private final ClassLoader classLoader;
private Configuration configuration;
public ConfigSupplier(URI uri, ClassLoader classLoader) {
this.uri = uri;
this.classLoader = classLoader;
this.configuration = null;
}
public ConfigSupplier(URI uri, Configuration configuration) {
this.uri = uri;
this.classLoader = configuration.getClassLoader();
this.configuration = configuration;
}
public URI getUri() {
public ClassLoader getClassLoader() {
public Configuration getConfiguration() {
CacheManager
public interface CacheManager extends Closeable {
<K, V, C extends Configuration<K, V>> Cache<K, V> createCache(String var1, C var2) throws IllegalArgumentException;
<K, V> Cache<K, V> getCache(String var1, Class<K> var2, Class<V> var3);
<K, V> Cache<K, V> getCache(String var1);
Iterable<String> getCacheNames();
void destroyCache(String var1);
CachingProvider getCachingProvider();
URI getURI();
ClassLoader getClassLoader();
Properties getProperties();
void enableManagement(String var1, boolean var2);
void enableStatistics(String var1, boolean var2);
void close();
boolean isClosed();
<T> T unwrap(Class<T> var1);
}
EhcacheManager
class Eh107CacheManager implements CacheManager {
private static final Logger LOG = LoggerFactory.getLogger(Eh107CacheManager.class);
private static final MBeanServer MBEAN_SERVER = ManagementFactory.getPlatformMBeanServer();
private final Object cachesLock = new Object();
private final ConcurrentMap<String, Eh107Cache<?, ?>> caches = new ConcurrentHashMap();
private final org.ehcache.CacheManager ehCacheManager;
private final EhcacheCachingProvider cachingProvider;
private final ClassLoader classLoader;
private final URI uri;
private final Properties props;
private final ConfigurationMerger configurationMerger;
private final StatisticsService statisticsService;
*************
構造方法
Eh107CacheManager(EhcacheCachingProvider cachingProvider, org.ehcache.CacheManager ehCacheManager, Jsr107Service jsr107Service, Properties props, ClassLoader classLoader, URI uri, ConfigurationMerger configurationMerger) {
*************
普通方法
public CachingProvider getCachingProvider() {
public <K, V, C extends Configuration<K, V>> javax.cache.Cache<K, V> createCache(String cacheName, C config) throws IllegalArgumentException {
public <K, V> javax.cache.Cache<K, V> getCache(String cacheName, Class<K> keyType, Class<V> valueType) {
public <K, V> javax.cache.Cache<K, V> getCache(String cacheName) {
public Iterable<String> getCacheNames() {
public void destroyCache(String cacheName) {
public URI getURI() {
public ClassLoader getClassLoader() {
public Properties getProperties() {
public void enableManagement(String cacheName, boolean enabled) {
private void enableManagement(Eh107Cache<?, ?> cache, boolean enabled) {
public void enableStatistics(String cacheName, boolean enabled) {
private void enableStatistics(Eh107Cache<?, ?> cache, boolean enabled) {
public boolean isClosed() {
public <T> T unwrap(Class<T> clazz) {
public String toString() {
public void close() {
void closeInternal() {
void close(Eh107Cache<?, ?> cache) {
private void checkClosed() {
private void refreshAllCaches() {
private <K, V> Eh107Cache<K, V> wrapEhcacheCache(String alias, CacheConfiguration<K, V> ehConfig) {
private <K, V> Eh107Cache<K, V> wrapEhcacheCache(String alias, InternalCache<K, V> cache) {
private <K, V> Jsr107CacheLoaderWriter<K, V> wrapCacheLoaderWriter(CacheLoaderWriter<K, V> cacheLoaderWriter) {
private <K, V> Eh107Cache<K, V> safeCacheRetrieval(String cacheName) {
private void unregisterObject(Eh107MXBean bean) {
private void registerObject(Eh107MXBean bean) {
Configuration:javax.cache jar包提供
public interface Configuration<K, V> extends Serializable {
Class<K> getKeyType();
Class<V> getValueType();
boolean isStoreByValue();
}
CompleteConfiguration
public interface CompleteConfiguration<K, V> extends Configuration<K, V>, Serializable {
boolean isReadThrough();
boolean isWriteThrough();
boolean isStatisticsEnabled();
boolean isManagementEnabled();
Iterable<CacheEntryListenerConfiguration<K, V>> getCacheEntryListenerConfigurations();
Factory<CacheLoader<K, V>> getCacheLoaderFactory();
Factory<CacheWriter<? super K, ? super V>> getCacheWriterFactory();
Factory<ExpiryPolicy> getExpiryPolicyFactory();
}
MutableConfiguration
public class MutableConfiguration<K, V> implements CompleteConfiguration<K, V> {
public static final long serialVersionUID = 201306200821L;
protected Class<K> keyType;
protected Class<V> valueType;
protected HashSet<CacheEntryListenerConfiguration<K, V>> listenerConfigurations;
protected Factory<CacheLoader<K, V>> cacheLoaderFactory;
protected Factory<CacheWriter<? super K, ? super V>> cacheWriterFactory;
protected Factory<ExpiryPolicy> expiryPolicyFactory;
protected boolean isReadThrough;
protected boolean isWriteThrough;
protected boolean isStatisticsEnabled;
protected boolean isStoreByValue;
protected boolean isManagementEnabled;
*************
構造方法
public MutableConfiguration() {
public MutableConfiguration(CompleteConfiguration<K, V> configuration) {
*************
普通方法
public Class<K> getKeyType() {
public Class<V> getValueType() {
public MutableConfiguration<K, V> setTypes(Class<K> keyType, Class<V> valueType) {
public Iterable<CacheEntryListenerConfiguration<K, V>> getCacheEntryListenerConfigurations() {
public MutableConfiguration<K, V> addCacheEntryListenerConfiguration(CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration) {
public MutableConfiguration<K, V> removeCacheEntryListenerConfiguration(CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration) {
public boolean isReadThrough() {
public boolean isWriteThrough() {
public boolean isStoreByValue() {
public boolean isStatisticsEnabled() {
public boolean isManagementEnabled() {
public Factory<ExpiryPolicy> getExpiryPolicyFactory() {
public Factory<CacheLoader<K, V>> getCacheLoaderFactory() {
public Factory<CacheWriter<? super K, ? super V>> getCacheWriterFactory() {
public MutableConfiguration<K, V> setReadThrough(boolean isReadThrough) {
public MutableConfiguration<K, V> setWriteThrough(boolean isWriteThrough) {
public MutableConfiguration<K, V> setStoreByValue(boolean isStoreByValue) {
public MutableConfiguration<K, V> setStatisticsEnabled(boolean enabled) {
public MutableConfiguration<K, V> setManagementEnabled(boolean enabled) {
public MutableConfiguration<K, V> setExpiryPolicyFactory(Factory<? extends ExpiryPolicy> factory) {
public MutableConfiguration<K, V> setCacheLoaderFactory(Factory<? extends CacheLoader<K, V>> factory) {
public MutableConfiguration<K, V> setCacheWriterFactory(Factory<? extends CacheWriter<? super K, ? super V>> factory) {
public int hashCode() {
public boolean equals(Object object) {
Configuration:ehcache jar包提供
public interface Configuration {
Map<String, CacheConfiguration<?, ?>> getCacheConfigurations();
Collection<ServiceCreationConfiguration<?, ?>> getServiceCreationConfigurations();
ClassLoader getClassLoader();
default FluentConfigurationBuilder<?> derive() {
throw new UnsupportedOperationException();
}
}
DefaultConfiguration
public final class DefaultConfiguration implements Configuration, HumanReadable {
private final ConcurrentMap<String, CacheConfiguration<?, ?>> caches;
private final Collection<ServiceCreationConfiguration<?, ?>> services;
private final ClassLoader classLoader;
**********
構造方法
public DefaultConfiguration(Configuration cfg) {
public DefaultConfiguration(ClassLoader classLoader, ServiceCreationConfiguration<?, ?>... services) {
public DefaultConfiguration(Map<String, CacheConfiguration<?, ?>> caches, ClassLoader classLoader, ServiceCreationConfiguration<?, ?>... services) {
**********
普通方法
public void addCacheConfiguration(String alias, CacheConfiguration<?, ?> config) {
public void removeCacheConfiguration(String alias) {
public <K, V> void replaceCacheConfiguration(String alias, CacheConfiguration<K, V> config, CacheRuntimeConfiguration<K, V> runtimeConfiguration) {
public ClassLoader getClassLoader() {
public FluentConfigurationBuilder<?> derive() {
public Map<String, CacheConfiguration<?, ?>> getCacheConfigurations() {
public Collection<ServiceCreationConfiguration<?, ?>> getServiceCreationConfigurations() {
public String readableString() {
private static Map<String, CacheConfiguration<?, ?>> emptyCacheMap() {
ServiceCreationConfiguration
public interface ServiceCreationConfiguration<T extends Service, R> {
Class<T> getServiceType();
default R derive() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
default ServiceCreationConfiguration<T, ?> build(R representation) throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
default boolean compatibleWith(ServiceCreationConfiguration<?, ?> other) {
return !this.getClass().isInstance(other);
}
}
DefaultPersistenceConfiguration:磁盤存儲路徑設定
public class DefaultPersistenceConfiguration implements ServiceCreationConfiguration<LocalPersistenceService, File> {
private final File rootDirectory;
public DefaultPersistenceConfiguration(File rootDirectory) {
this.rootDirectory = rootDirectory;
}
public File getRootDirectory() {
return this.rootDirectory;
}
public Class<LocalPersistenceService> getServiceType() {
return LocalPersistenceService.class;
}
public File derive() {
return this.getRootDirectory();
}
public DefaultPersistenceConfiguration build(File file) {
return new DefaultPersistenceConfiguration(file);
}
}
DefaultSerializationProviderConfiguration:自定義序列化類
public class DefaultSerializationProviderConfiguration implements ServiceCreationConfiguration<SerializationProvider, DefaultSerializationProviderConfiguration> {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultSerializationProviderConfiguration.class);
private final Map<Class<?>, Class<? extends Serializer<?>>> defaultSerializers = new LinkedHashMap();
*********
構造方法
public DefaultSerializationProviderConfiguration() {
public DefaultSerializationProviderConfiguration(DefaultSerializationProviderConfiguration other) {
*********
普通方法
public <T> DefaultSerializationProviderConfiguration addSerializerFor(Class<T> serializableClass, Class<? extends Serializer<T>> serializerClass) {
public <T> DefaultSerializationProviderConfiguration addSerializerFor(Class<T> serializableClass, Class<? extends Serializer<T>> serializerClass, boolean overwrite) {
public Map<Class<?>, Class<? extends Serializer<?>>> getDefaultSerializers() {
public Class<SerializationProvider> getServiceType() {
public DefaultSerializationProviderConfiguration derive() {
public DefaultSerializationProviderConfiguration build(DefaultSerializationProviderConfiguration configuration) {
private static boolean isConstructorPresent(Class<?> clazz, Class<?>... args) {
************************
示例
@Data
class Student{
private String name;
private Integer age;
}
public class Test2 {
public static void main(String[] args){
CachingProvider cachingProvider= Caching.getCachingProvider(EhcacheCachingProvider.class.getName());
CacheManager cacheManager=cachingProvider.getCacheManager();
MutableConfiguration<String,Student> mutableConfiguration=new MutableConfiguration<String,Student>()
.setTypes(String.class,Student.class)
.setStoreByValue(false)
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(new Duration(TimeUnit.MINUTES,5)));
Cache<String,Student> cache=cacheManager.createCache("custom",mutableConfiguration);
Student student=new Student();
student.setName("瓜田李下");
student.setAge(20);
cache.put("1",student);
System.out.println(cache.get("1"));
}
}
*******************
控制台輸出
18:14:03.286 [main] DEBUG org.ehcache.core.spi.ServiceLocator - Starting 18 Services...
18:14:03.296 [main] DEBUG org.ehcache.core.internal.statistics.DefaultStatisticsService - Starting service
18:14:03.298 [main] DEBUG org.ehcache.core.spi.ServiceLocator - All Services successfully started, 18 Services in 14ms
18:14:03.299 [main] DEBUG org.ehcache.core.internal.statistics.DefaultStatisticsService - Moving from UNINITIALIZED to AVAILABLE
18:14:03.301 [main] DEBUG org.ehcache.core.EhcacheManager - Initialize successful.
18:14:03.500 [main] DEBUG org.ehcache.core.EhcacheManager - Creating Cache 'custom' in EhcacheManager.
18:14:03.503 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for <java.lang.String> : [email protected]
18:14:03.506 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for <com.example.demo.test.Student> : [email protected]
18:14:03.529 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <java.lang.String> : [email protected]
18:14:03.529 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <com.example.demo.test.Student> : [email protected]
18:14:03.568 [main] DEBUG org.ehcache.impl.internal.store.heap.OnHeapStore - TTI or custom expiration strategy detected
18:14:03.625 [main] DEBUG class org.ehcache.core.Ehcache-custom - Initialize successful.
18:14:03.625 [main] DEBUG org.ehcache.core.internal.statistics.DefaultStatisticsService - Cache added custom
18:14:03.637 [main] INFO org.ehcache.core.EhcacheManager - Cache 'custom' created in EhcacheManager.
Student(name=瓜田李下, age=20)
************************
示例 2
PersonSerializer
public class PersonSerializer implements Serializer<Person> {
public PersonSerializer(){
}
public PersonSerializer(ClassLoader classLoader){
}
@Override
public ByteBuffer serialize(Person person) throws SerializerException {
return ByteBuffer.wrap(JSONObject.toJSONBytes(person));
}
@Override
public Person read(ByteBuffer byteBuffer) throws ClassNotFoundException, SerializerException {
return JSONObject.parseObject(byteBuffer.array(),Person.class);
}
@Override
public boolean equals(Person person, ByteBuffer byteBuffer) throws ClassNotFoundException, SerializerException {
return person.equals(JSONObject.parseObject(byteBuffer.array(),Person.class));
}
}
@Data
class Person{
private String name;
private Integer age;
}
public class Test3 {
public static void main(String[] args){
EhcacheCachingProvider cachingProvider=(EhcacheCachingProvider) Caching.getCachingProvider(EhcacheCachingProvider.class.getName());
DefaultSerializationProviderConfiguration serializationProviderConfiguration=new DefaultSerializationProviderConfiguration();
serializationProviderConfiguration.addSerializerFor(Person.class,PersonSerializer.class);
DefaultConfiguration configuration=new DefaultConfiguration(cachingProvider.getDefaultClassLoader(),
new DefaultSerializationProviderConfiguration(serializationProviderConfiguration),
new DefaultPersistenceConfiguration(new File("d:"+File.separator+"cache")));
configuration.addCacheConfiguration("custom", CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class,Person.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, MemoryUnit.MB).disk(100,MemoryUnit.MB).build())
.build());
CacheManager cacheManager= cachingProvider.getCacheManager(cachingProvider.getDefaultURI(),configuration);
Cache<String,Person> cache=cacheManager.getCache("custom");
Person person=new Person();
person.setName("瓜田李下");
person.setAge(20);
cache.put("1",person);
System.out.println(cache.get("1"));
}
}
*******************
控制台輸出
18:56:22.466 [main] DEBUG org.ehcache.core.spi.ServiceLocator - Starting 21 Services...
18:56:22.485 [main] DEBUG org.ehcache.impl.persistence.DefaultLocalPersistenceService - RootDirectory Locked
18:56:22.485 [main] DEBUG org.ehcache.core.internal.statistics.DefaultStatisticsService - Starting service
18:56:22.494 [main] DEBUG org.ehcache.core.spi.ServiceLocator - All Services successfully started, 21 Services in 30ms
18:56:22.495 [main] DEBUG org.ehcache.core.EhcacheManager - Creating Cache 'custom' in EhcacheManager.
18:56:22.527 [main] DEBUG org.ehcache.impl.persistence.DefaultLocalPersistenceService - Destroying file based persistence context for custom
18:56:22.920 [main] DEBUG org.terracotta.utilities.io.Files - [deleteTreeWithRetry] Deleting "D:\cache\file\custom_f9ac14b63a75faf57d8db6f919bfabb2502d273c"
18:56:22.921 [main] DEBUG org.terracotta.utilities.io.Files - Renaming "D:\cache\file\custom_f9ac14b63a75faf57d8db6f919bfabb2502d273c" to "D:\cache\file\del7596624902040514510"
18:56:22.922 [main] DEBUG org.terracotta.utilities.io.Files - Deleting "D:\cache\file\del7596624902040514510" renamed from "D:\cache\file\custom_f9ac14b63a75faf57d8db6f919bfabb2502d273c"
18:56:22.928 [main] DEBUG org.terracotta.utilities.io.Files - Deletion complete for "D:\cache\file\del7596624902040514510"
18:56:22.929 [main] DEBUG org.ehcache.impl.persistence.FileUtils - Reusing d:\cache\file
18:56:22.929 [main] DEBUG org.ehcache.impl.persistence.FileUtils - Created d:\cache\file\custom_f9ac14b63a75faf57d8db6f919bfabb2502d273c
18:56:22.931 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for <java.lang.String> : [email protected]
18:56:22.932 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for <com.example.demo.test.Person> : [email protected]
18:56:22.950 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <java.lang.String> : [email protected]
18:56:22.950 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <com.example.demo.test.Person> : [email protected]
18:56:22.953 [main] INFO org.ehcache.sizeof.filters.AnnotationSizeOfFilter - Using regular expression provided through VM argument org.ehcache.sizeof.filters.AnnotationSizeOfFilter.pattern for IgnoreSizeOf annotation : ^.*cache\..*IgnoreSizeOf$
18:56:23.053 [main] INFO org.ehcache.sizeof.impl.JvmInformation - Detected JVM data model settings of: 64-Bit HotSpot JVM with Compressed OOPs
18:56:23.117 [main] INFO org.ehcache.sizeof.impl.AgentLoader - Failed to attach to VM and load the agent: class java.io.IOException: Can not attach to current VM
18:56:23.155 [main] DEBUG org.ehcache.impl.internal.store.heap.OnHeapStore - No expiration strategy detected
18:56:23.257 [main] DEBUG org.ehcache.impl.persistence.FileUtils - Created d:\cache\file\custom_f9ac14b63a75faf57d8db6f919bfabb2502d273c\offheap-disk-store
18:56:23.433 [main] DEBUG class org.ehcache.core.Ehcache-custom - Initialize successful.
18:56:23.433 [main] INFO org.ehcache.core.EhcacheManager - Cache 'custom' created in EhcacheManager.
18:56:23.433 [main] DEBUG org.ehcache.core.internal.statistics.DefaultStatisticsService - Moving from UNINITIALIZED to AVAILABLE
18:56:23.433 [main] DEBUG org.ehcache.core.internal.statistics.DefaultStatisticsService - Cache added custom
18:56:23.461 [main] DEBUG org.ehcache.core.EhcacheManager - Initialize successful.
18:56:23.482 [main] INFO org.ehcache.jsr107.Eh107CacheManager - Registering Ehcache MBean javax.cache:type=CacheStatistics,CacheManager=urn.X-ehcache.jsr107-default-config,Cache=custom
18:56:23.766 [main] DEBUG org.ehcache.sizeof.filters.AnnotationSizeOfFilter - org.ehcache.sizeof.annotations.IgnoreSizeOf matched IgnoreSizeOf annotation pattern ^.*cache\..*IgnoreSizeOf$
Person(name=瓜田李下, age=20)