天天看點

ehcache jsr 使用

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)