HHH-6796 - Services retrieved after SessionFactoryServiceRegistry has started are not configured (Configurable)
This commit is contained in:
parent
4739c5dc0c
commit
3c3482bd59
|
@ -51,15 +51,20 @@ import org.hibernate.service.spi.Stoppable;
|
|||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImplementor, ServiceBinding.OwningRegistry {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, AbstractServiceRegistryImpl.class.getName() );
|
||||
public abstract class AbstractServiceRegistryImpl
|
||||
implements ServiceRegistryImplementor, ServiceBinding.ServiceLifecycleOwner {
|
||||
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
AbstractServiceRegistryImpl.class.getName()
|
||||
);
|
||||
|
||||
private final ServiceRegistryImplementor parent;
|
||||
|
||||
private ConcurrentHashMap<Class,ServiceBinding> serviceBindingMap;
|
||||
// IMPL NOTE : the list used for ordered destruction. Cannot used map above because we need to
|
||||
// iterate it in reverse order which is only available through ListIterator
|
||||
private List<Service> serviceList = new ArrayList<Service>();
|
||||
private List<ServiceBinding> serviceBindingList = new ArrayList<ServiceBinding>();
|
||||
|
||||
@SuppressWarnings( {"UnusedDeclaration"})
|
||||
protected AbstractServiceRegistryImpl() {
|
||||
|
@ -75,7 +80,7 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
private void prepare() {
|
||||
// assume 20 services for initial sizing
|
||||
this.serviceBindingMap = CollectionHelper.concurrentMap( 20 );
|
||||
this.serviceList = CollectionHelper.arrayList( 20 );
|
||||
this.serviceBindingList = CollectionHelper.arrayList( 20 );
|
||||
}
|
||||
|
||||
public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||
|
@ -138,12 +143,8 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
}
|
||||
|
||||
protected <R extends Service> void registerService(ServiceBinding<R> serviceBinding, R service) {
|
||||
R priorServiceInstance = serviceBinding.getService();
|
||||
serviceBinding.setService( service );
|
||||
if ( priorServiceInstance != null ) {
|
||||
serviceList.remove( priorServiceInstance );
|
||||
}
|
||||
serviceList.add( service );
|
||||
serviceBindingList.add( serviceBinding );
|
||||
}
|
||||
|
||||
private <R extends Service> R initializeService(ServiceBinding<R> serviceBinding) {
|
||||
|
@ -158,25 +159,18 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
}
|
||||
|
||||
// PHASE 2 : inject service (***potentially recursive***)
|
||||
injectService( service );
|
||||
serviceBinding.getLifecycleOwner().injectDependencies( serviceBinding );
|
||||
|
||||
// PHASE 3 : configure service
|
||||
serviceBinding.getServiceRegistry().configureService( service );
|
||||
serviceBinding.getLifecycleOwner().configureService( serviceBinding );
|
||||
|
||||
// PHASE 4 : Start service
|
||||
serviceBinding.getLifecycleOwner().startService( serviceBinding );
|
||||
startService( serviceBinding );
|
||||
|
||||
return service;
|
||||
}
|
||||
|
||||
protected <T extends Service> void injectService(T service) {
|
||||
applyInjections( service );
|
||||
|
||||
if ( ServiceRegistryAwareService.class.isInstance( service ) ) {
|
||||
( (ServiceRegistryAwareService) service ).injectServices( this );
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
protected <R extends Service> R createService(ServiceBinding<R> serviceBinding) {
|
||||
final ServiceInitiator<R> serviceInitiator = serviceBinding.getServiceInitiator();
|
||||
|
@ -186,7 +180,7 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
}
|
||||
|
||||
try {
|
||||
R service = serviceBinding.getServiceRegistry().initiateService( serviceInitiator );
|
||||
R service = serviceBinding.getLifecycleOwner().initiateService( serviceInitiator );
|
||||
// IMPL NOTE : the register call here is important to avoid potential stack overflow issues
|
||||
// from recursive calls through #configureService
|
||||
registerService( serviceBinding, service );
|
||||
|
@ -200,7 +194,18 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
}
|
||||
}
|
||||
|
||||
protected <T extends Service> void applyInjections(T service) {
|
||||
@Override
|
||||
public <R extends Service> void injectDependencies(ServiceBinding<R> serviceBinding) {
|
||||
final R service = serviceBinding.getService();
|
||||
|
||||
applyInjections( service );
|
||||
|
||||
if ( ServiceRegistryAwareService.class.isInstance( service ) ) {
|
||||
( (ServiceRegistryAwareService) service ).injectServices( this );
|
||||
}
|
||||
}
|
||||
|
||||
private <R extends Service> void applyInjections(R service) {
|
||||
try {
|
||||
for ( Method method : service.getClass().getMethods() ) {
|
||||
InjectService injectService = method.getAnnotation( InjectService.class );
|
||||
|
@ -208,7 +213,7 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
continue;
|
||||
}
|
||||
|
||||
applyInjection( service, method, injectService );
|
||||
processInjection( service, method, injectService );
|
||||
}
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
|
@ -217,7 +222,7 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
private <T extends Service> void applyInjection(T service, Method injectionMethod, InjectService injectService) {
|
||||
private <T extends Service> void processInjection(T service, Method injectionMethod, InjectService injectService) {
|
||||
if ( injectionMethod.getParameterTypes() == null || injectionMethod.getParameterTypes().length != 1 ) {
|
||||
throw new ServiceDependencyException(
|
||||
"Encountered @InjectService on method with unexpected number of parameters"
|
||||
|
@ -249,8 +254,9 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected <R extends Service> void startService(ServiceBinding<R> serviceBinding) {
|
||||
public <R extends Service> void startService(ServiceBinding<R> serviceBinding) {
|
||||
if ( Startable.class.isInstance( serviceBinding.getService() ) ) {
|
||||
( (Startable) serviceBinding.getService() ).start();
|
||||
}
|
||||
|
@ -262,24 +268,31 @@ public abstract class AbstractServiceRegistryImpl implements ServiceRegistryImpl
|
|||
);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
public void destroy() {
|
||||
ListIterator<Service> serviceIterator = serviceList.listIterator( serviceList.size() );
|
||||
while ( serviceIterator.hasPrevious() ) {
|
||||
final Service service = serviceIterator.previous();
|
||||
if ( Stoppable.class.isInstance( service ) ) {
|
||||
try {
|
||||
( (Stoppable) service ).stop();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
LOG.unableToStopService( service.getClass(), e.toString() );
|
||||
}
|
||||
}
|
||||
ListIterator<ServiceBinding> serviceBindingsIterator = serviceBindingList.listIterator( serviceBindingList.size() );
|
||||
while ( serviceBindingsIterator.hasPrevious() ) {
|
||||
final ServiceBinding serviceBinding = serviceBindingsIterator.previous();
|
||||
serviceBinding.getLifecycleOwner().stopService( serviceBinding );
|
||||
}
|
||||
serviceList.clear();
|
||||
serviceList = null;
|
||||
serviceBindingList.clear();
|
||||
serviceBindingList = null;
|
||||
serviceBindingMap.clear();
|
||||
serviceBindingMap = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends Service> void stopService(ServiceBinding<R> binding) {
|
||||
final Service service = binding.getService();
|
||||
if ( Stoppable.class.isInstance( service ) ) {
|
||||
try {
|
||||
( (Stoppable) service ).stop();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
LOG.unableToStopService( service.getClass(), e.toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ import org.hibernate.service.spi.ServiceRegistryImplementor;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BootstrapServiceRegistryImpl
|
||||
implements ServiceRegistryImplementor, BootstrapServiceRegistry, ServiceBinding.OwningRegistry {
|
||||
implements ServiceRegistryImplementor, BootstrapServiceRegistry, ServiceBinding.ServiceLifecycleOwner {
|
||||
private static final LinkedHashSet<Integrator> NO_INTEGRATORS = new LinkedHashSet<Integrator>();
|
||||
|
||||
private final ServiceBinding<ClassLoaderService> classLoaderServiceBinding;
|
||||
|
@ -112,13 +112,27 @@ public class BootstrapServiceRegistryImpl
|
|||
|
||||
@Override
|
||||
public <R extends Service> R initiateService(ServiceInitiator<R> serviceInitiator) {
|
||||
// the bootstrap registry should currently be made up of only directly built services.
|
||||
throw new ServiceException( "Boot-strap registry should only contain directly built services" );
|
||||
throw new ServiceException( "Boot-strap registry should only contain provided services" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends Service> void configureService(R service) {
|
||||
//nothing do to for bootstrap style services
|
||||
public <R extends Service> void configureService(ServiceBinding<R> binding) {
|
||||
throw new ServiceException( "Boot-strap registry should only contain provided services" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends Service> void injectDependencies(ServiceBinding<R> binding) {
|
||||
throw new ServiceException( "Boot-strap registry should only contain provided services" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends Service> void startService(ServiceBinding<R> binding) {
|
||||
throw new ServiceException( "Boot-strap registry should only contain provided services" );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R extends Service> void stopService(ServiceBinding<R> binding) {
|
||||
throw new ServiceException( "Boot-strap registry should only contain provided services" );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ import org.hibernate.cfg.Configuration;
|
|||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||
import org.hibernate.metamodel.source.MetadataImplementor;
|
||||
import org.hibernate.service.Service;
|
||||
import org.hibernate.service.spi.ServiceBinding;
|
||||
import org.hibernate.service.spi.ServiceInitiator;
|
||||
import org.hibernate.service.spi.ServiceRegistryAwareService;
|
||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||
import org.hibernate.service.spi.SessionFactoryServiceInitiator;
|
||||
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
|
||||
|
@ -96,7 +96,7 @@ public class SessionFactoryServiceRegistryImpl extends AbstractServiceRegistryIm
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T extends Service> void configureService(T service) {
|
||||
public <R extends Service> void configureService(ServiceBinding<R> serviceBinding) {
|
||||
//TODO nothing to do here or should we inject SessionFactory properties?
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ import org.hibernate.service.Service;
|
|||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.spi.BasicServiceInitiator;
|
||||
import org.hibernate.service.spi.Configurable;
|
||||
import org.hibernate.service.spi.ServiceBinding;
|
||||
import org.hibernate.service.spi.ServiceInitiator;
|
||||
import org.hibernate.service.spi.ServiceRegistryAwareService;
|
||||
|
||||
/**
|
||||
* Hibernate implementation of the standard service registry.
|
||||
|
@ -70,9 +70,9 @@ public class StandardServiceRegistryImpl extends AbstractServiceRegistryImpl imp
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T extends Service> void configureService(T service) {
|
||||
if ( Configurable.class.isInstance( service ) ) {
|
||||
( (Configurable) service ).configure( configurationValues );
|
||||
public <R extends Service> void configureService(ServiceBinding<R> serviceBinding) {
|
||||
if ( Configurable.class.isInstance( serviceBinding.getService() ) ) {
|
||||
( (Configurable) serviceBinding.getService() ).configure( configurationValues );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,31 +35,36 @@ import org.hibernate.service.Service;
|
|||
public final class ServiceBinding<R extends Service> {
|
||||
private static final Logger log = Logger.getLogger( ServiceBinding.class );
|
||||
|
||||
public static interface OwningRegistry {
|
||||
public static interface ServiceLifecycleOwner {
|
||||
public <R extends Service> R initiateService(ServiceInitiator<R> serviceInitiator);
|
||||
public <R extends Service> void configureService(R service);
|
||||
|
||||
public <R extends Service> void configureService(ServiceBinding<R> binding);
|
||||
public <R extends Service> void injectDependencies(ServiceBinding<R> binding);
|
||||
public <R extends Service> void startService(ServiceBinding<R> binding);
|
||||
|
||||
public <R extends Service> void stopService(ServiceBinding<R> binding);
|
||||
}
|
||||
|
||||
private final OwningRegistry serviceRegistry;
|
||||
private final ServiceLifecycleOwner lifecycleOwner;
|
||||
private final Class<R> serviceRole;
|
||||
private final ServiceInitiator<R> serviceInitiator;
|
||||
private R service;
|
||||
|
||||
public ServiceBinding(OwningRegistry serviceRegistry, Class<R> serviceRole, R service) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
public ServiceBinding(ServiceLifecycleOwner lifecycleOwner, Class<R> serviceRole, R service) {
|
||||
this.lifecycleOwner = lifecycleOwner;
|
||||
this.serviceRole = serviceRole;
|
||||
this.serviceInitiator = null;
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public ServiceBinding(OwningRegistry serviceRegistry, ServiceInitiator<R> serviceInitiator) {
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
public ServiceBinding(ServiceLifecycleOwner lifecycleOwner, ServiceInitiator<R> serviceInitiator) {
|
||||
this.lifecycleOwner = lifecycleOwner;
|
||||
this.serviceRole = serviceInitiator.getServiceInitiated();
|
||||
this.serviceInitiator = serviceInitiator;
|
||||
}
|
||||
|
||||
public OwningRegistry getServiceRegistry() {
|
||||
return serviceRegistry;
|
||||
public ServiceLifecycleOwner getLifecycleOwner() {
|
||||
return lifecycleOwner;
|
||||
}
|
||||
|
||||
public Class<R> getServiceRole() {
|
||||
|
|
Loading…
Reference in New Issue