All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openthinks.libs.utilities.lookup.LookupPool Maven / Gradle / Ivy

The newest version!
package com.openthinks.libs.utilities.lookup;

import java.util.Optional;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.openthinks.libs.utilities.Checker;
import com.openthinks.libs.utilities.InstanceUtilities;
import com.openthinks.libs.utilities.InstanceUtilities.InstanceWrapper;
import com.openthinks.libs.utilities.pools.object.ObjectPool;


/**
 * ClassName: LookupPool 
* Function: It is used for store shared object instances and find other SPI
* Reason: follow the design pattern of fly weight to reduce instantiate new * object.
* Notice: avoid store or find those object which include its own state and will * be changed;
* Usage:
* *
 * 
 * //get gloabl instance of LookupPool
 * LookupPool lookupPool = LookupPools.gloabl();
 * 
 * //get a named instance of LookupPool
 * lookupPool = LookupPools.get("pool-1");
 * 
 * // instance by class directly
 * LookupInterfaceImpl instanceImpl1 = lookupPool.lookup(LookupInterfaceImpl.class);
 * 
 * // instance by customized implementation class
 * LookupInterface instanceImpl2 = lookupPool.lookup(LookupInterface.class,InstanceWrapper.build(LookupInterfaceImpl.class));
 * 
 * // lookup shared object already existed
 * LookupInterface instanceImpl3 = lookupPool.lookup(LookupInterface.class);
 * assert instanceImpl2==instanceImpl3 ;
 * 
 * // register a shared object by name
 * lookupPool.register("beanName1",instanceImpl1);
 * // lookup shared object by name
 * LookupInterface instanceImpl4 = lookupPool.lookup("beanName1");
 * 
 * assert instanceImpl1==instanceImpl4 ;
 * 
 * // clear all shared objects and mappings
 * lookupPool.cleanUp();
 * 
 * 
 * 
* * date: Sep 8, 2017 3:15:29 PM
* * @author [email protected] * @version 1.0 * @since JDK 1.8 */ public abstract class LookupPool { protected final ObjectPool objectPool; protected final ReadWriteLock lock; public abstract String name(); LookupPool() { objectPool = new ObjectPool(); lock = new ReentrantReadWriteLock(); } /** * lookup a object by its type, if not find firstly, try to instance by * instanceType and constructor parameters args * * @param * lookup object type * @param type * Class lookup key type * @param args * Object[] instance constructor parameters * @return T lookup object or null */ public T lookup(Class type, Object... args) { return lookup(type, null, args); } /** * lookup a object by its type, if not find firstly, try to instance by * instanceType and constructor parameters args * * @param * lookup object type * @param * lookup object type * @param searchType * Class lookup key type * @param instancewrapper * Class instance type when not lookup the key * @param args * Object[] instance constructor parameters * @return T lookup object or null */ public T lookup(final Class searchType, InstanceWrapper instancewrapper, Object... args) { T object = null; lock.readLock().lock(); try { object = objectPool.get(searchType); } finally { lock.readLock().unlock(); } if (object == null) { lock.writeLock().lock(); try { object = InstanceUtilities.create(searchType, instancewrapper, args); register(searchType, object); } finally { lock.writeLock().unlock(); } } return object; } /** * look up object by its bean name * * @param * lookup object type * @param beanName * String lookup object mapping name * @return T lookup object or null */ public T lookup(String beanName) { lock.readLock().lock(); try { return objectPool.get(beanName); } finally { lock.readLock().unlock(); } } /** * lookup a optional object by its type, if not find firstly, try to instance by * instanceType and constructor parameters args * * @param * lookup object type * @param type * Class lookup key type * @param args * Object[] instance constructor parameters * @return Optional of lookup object */ public Optional lookupIf(Class type, Object... args) { return Optional.ofNullable(lookup(type, args)); } /** * lookup a optional object by its type, if not find firstly, try to instance by * instanceType and constructor parameters args * * @param * lookup object type * @param * lookup object type * @param searchType * Class lookup key type * @param instancewrapper * Class instance type when not lookup the key * @param args * Object[] instance constructor parameters * @return Optional of lookup object */ public Optional lookupIf(final Class searchType, InstanceWrapper instancewrapper, Object... args) { return Optional.ofNullable(lookup(searchType, instancewrapper, args)); } /** * look up optional object by its bean name * * @param * lookup object type * @param beanName * String lookup object mapping name * @return Optional of lookup object */ public Optional lookupIf(String beanName) { return Optional.ofNullable(lookup(beanName)); } /** * * lookupSPI:this will used {@link ServiceLoader} to load SPI which defined in * folder META-INF/services.
* It will first to try to load instance from cached {@link ObjectPool}, if not * found, then try to load SPI class and instantiate it.
* Notice: only load and instantiate first SPI class in defined file
* * @param * lookup SPI interface class * @param spiInterface * SPI interface or abstract class type * @param args * constructor arguments * @return implementation of parameter spiInterface */ public T lookupSPI(Class spiInterface, Object... args) { return lookupFocusSPI(spiInterface, null, args); } /** * * lookupFocusSPI:this will used {@link ServiceLoader} to load SPI which defined * in folder META-INF/services.
* It will first to try to load instance from cached {@link ObjectPool}, if not * found, then try to load SPI class and instantiate it.
* Notice: only load and instantiate focused SPI class in defined file
* * @param * lookup SPI interface class * @param spiInterface * SPI interface or abstract class type * @param focusClassName * focused SPI implementation class aname * @param args * constructor arguments * @return implementation of parameter spiInterface * */ public T lookupFocusSPI(Class spiInterface, String focusClassName, Object... args) { T object = null; lock.readLock().lock(); try { object = objectPool.get(spiInterface); } finally { lock.readLock().unlock(); } if (object == null) { lock.writeLock().lock(); try { ServiceLoader serviceLoader = ServiceLoader.load(spiInterface, focusClassName, args); object = serviceLoader.iterator().next(); Checker.require(object).notNull("Cannot found SPI implementation for " + spiInterface); register(spiInterface, object); } finally { lock.writeLock().unlock(); } } return object; } /** * * register an instance, which key is object.getClass().
* * @param * registered object class type * @param object * instance which need registered */ public void register(T object) { if (object != null) { lock.writeLock().tryLock(); try { objectPool.put(object.getClass(), object); } finally { lock.writeLock().unlock(); } } } /** * register an instance, which key is given parameter classType * * @param * registered object class type * @param classType * Class as the key for registered instance * @param object * instance which need registered */ public void register(Class classType, T object) { if (object != null) { lock.writeLock().tryLock(); try { objectPool.put(classType, object); } finally { lock.writeLock().unlock(); } } } /** * register object and mapping it to given bean name * * @param * register object type * @param beanName * String bean name * @param object * register object */ public void register(String beanName, T object) { if (object != null) { lock.writeLock().lock(); try { objectPool.put(beanName, object); } finally { lock.writeLock().unlock(); } } } void cleanUp() { lock.writeLock().lock(); try { objectPool.cleanUp(); } finally { lock.writeLock().unlock(); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy