HHH-8923 - Reconsider closing of ServiceRegistry instances
Conflicts: hibernate-core/src/main/java/org/hibernate/boot/registry/StandardServiceRegistryBuilder.java
This commit is contained in:
parent
96b9366f14
commit
33aeb4f7c2
|
@ -51,10 +51,13 @@ import org.hibernate.integrator.spi.Integrator;
|
||||||
*/
|
*/
|
||||||
public class BootstrapServiceRegistryBuilder {
|
public class BootstrapServiceRegistryBuilder {
|
||||||
private final LinkedHashSet<Integrator> providedIntegrators = new LinkedHashSet<Integrator>();
|
private final LinkedHashSet<Integrator> providedIntegrators = new LinkedHashSet<Integrator>();
|
||||||
|
|
||||||
private List<ClassLoader> providedClassLoaders;
|
private List<ClassLoader> providedClassLoaders;
|
||||||
private ClassLoaderService providedClassLoaderService;
|
private ClassLoaderService providedClassLoaderService;
|
||||||
private StrategySelectorBuilder strategySelectorBuilder = new StrategySelectorBuilder();
|
private StrategySelectorBuilder strategySelectorBuilder = new StrategySelectorBuilder();
|
||||||
|
|
||||||
|
private boolean autoCloseRegistry = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an {@link Integrator} to be applied to the bootstrap registry.
|
* Add an {@link Integrator} to be applied to the bootstrap registry.
|
||||||
*
|
*
|
||||||
|
@ -190,6 +193,35 @@ public class BootstrapServiceRegistryBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, when a ServiceRegistry is no longer referenced by any other
|
||||||
|
* registries as a parent it will be closed.
|
||||||
|
* <p/>
|
||||||
|
* Some applications that explicitly build "shared registries" may want to
|
||||||
|
* circumvent that behavior.
|
||||||
|
* <p/>
|
||||||
|
* This method indicates that the registry being built should not be
|
||||||
|
* automatically closed. The caller agrees to take responsibility to
|
||||||
|
* close it themselves.
|
||||||
|
*
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public BootstrapServiceRegistryBuilder disableAutoClose() {
|
||||||
|
this.autoCloseRegistry = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See the discussion on {@link #disableAutoClose}. This method enables
|
||||||
|
* the auto-closing.
|
||||||
|
*
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public BootstrapServiceRegistryBuilder enableAutoClose() {
|
||||||
|
this.autoCloseRegistry = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the bootstrap registry.
|
* Build the bootstrap registry.
|
||||||
*
|
*
|
||||||
|
@ -219,6 +251,7 @@ public class BootstrapServiceRegistryBuilder {
|
||||||
|
|
||||||
|
|
||||||
return new BootstrapServiceRegistryImpl(
|
return new BootstrapServiceRegistryImpl(
|
||||||
|
autoCloseRegistry,
|
||||||
classLoaderService,
|
classLoaderService,
|
||||||
strategySelectorBuilder.buildSelector( classLoaderService ),
|
strategySelectorBuilder.buildSelector( classLoaderService ),
|
||||||
integratorService
|
integratorService
|
||||||
|
|
|
@ -61,6 +61,8 @@ public class StandardServiceRegistryBuilder {
|
||||||
private final List<StandardServiceInitiator> initiators = standardInitiatorList();
|
private final List<StandardServiceInitiator> initiators = standardInitiatorList();
|
||||||
private final List<ProvidedService> providedServices = new ArrayList<ProvidedService>();
|
private final List<ProvidedService> providedServices = new ArrayList<ProvidedService>();
|
||||||
|
|
||||||
|
private boolean autoCloseRegistry = true;
|
||||||
|
|
||||||
private final BootstrapServiceRegistry bootstrapServiceRegistry;
|
private final BootstrapServiceRegistry bootstrapServiceRegistry;
|
||||||
private final ConfigLoader configLoader;
|
private final ConfigLoader configLoader;
|
||||||
|
|
||||||
|
@ -202,6 +204,35 @@ public class StandardServiceRegistryBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* By default, when a ServiceRegistry is no longer referenced by any other
|
||||||
|
* registries as a parent it will be closed.
|
||||||
|
* <p/>
|
||||||
|
* Some applications that explicitly build "shared registries" may want to
|
||||||
|
* circumvent that behavior.
|
||||||
|
* <p/>
|
||||||
|
* This method indicates that the registry being built should not be
|
||||||
|
* automatically closed. The caller agrees to take responsibility to
|
||||||
|
* close it themselves.
|
||||||
|
*
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public StandardServiceRegistryBuilder disableAutoClose() {
|
||||||
|
this.autoCloseRegistry = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See the discussion on {@link #disableAutoClose}. This method enables
|
||||||
|
* the auto-closing.
|
||||||
|
*
|
||||||
|
* @return this, for method chaining
|
||||||
|
*/
|
||||||
|
public StandardServiceRegistryBuilder enableAutoClose() {
|
||||||
|
this.autoCloseRegistry = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the StandardServiceRegistry.
|
* Build the StandardServiceRegistry.
|
||||||
*
|
*
|
||||||
|
@ -217,7 +248,13 @@ public class StandardServiceRegistryBuilder {
|
||||||
applyServiceContributingIntegrators();
|
applyServiceContributingIntegrators();
|
||||||
applyServiceContributors();
|
applyServiceContributors();
|
||||||
|
|
||||||
return new StandardServiceRegistryImpl( bootstrapServiceRegistry, initiators, providedServices, settingsCopy );
|
return new StandardServiceRegistryImpl(
|
||||||
|
autoCloseRegistry,
|
||||||
|
bootstrapServiceRegistry,
|
||||||
|
initiators,
|
||||||
|
providedServices,
|
||||||
|
settingsCopy
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
|
|
|
@ -45,8 +45,6 @@ import org.hibernate.service.spi.ServiceInitiator;
|
||||||
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
import org.hibernate.service.spi.ServiceRegistryImplementor;
|
||||||
import org.hibernate.service.spi.Stoppable;
|
import org.hibernate.service.spi.Stoppable;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link ServiceRegistry} implementation containing specialized "bootstrap" services, specifically:<ul>
|
* {@link ServiceRegistry} implementation containing specialized "bootstrap" services, specifically:<ul>
|
||||||
* <li>{@link ClassLoaderService}</li>
|
* <li>{@link ClassLoaderService}</li>
|
||||||
|
@ -66,6 +64,7 @@ public class BootstrapServiceRegistryImpl
|
||||||
|
|
||||||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BootstrapServiceRegistryImpl.class );
|
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( BootstrapServiceRegistryImpl.class );
|
||||||
|
|
||||||
|
private final boolean autoCloseRegistry;
|
||||||
private boolean active = true;
|
private boolean active = true;
|
||||||
|
|
||||||
private static final LinkedHashSet<Integrator> NO_INTEGRATORS = new LinkedHashSet<Integrator>();
|
private static final LinkedHashSet<Integrator> NO_INTEGRATORS = new LinkedHashSet<Integrator>();
|
||||||
|
@ -87,7 +86,6 @@ public class BootstrapServiceRegistryImpl
|
||||||
public BootstrapServiceRegistryImpl() {
|
public BootstrapServiceRegistryImpl() {
|
||||||
this( new ClassLoaderServiceImpl(), NO_INTEGRATORS );
|
this( new ClassLoaderServiceImpl(), NO_INTEGRATORS );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a BootstrapServiceRegistryImpl.
|
* Constructs a BootstrapServiceRegistryImpl.
|
||||||
*
|
*
|
||||||
|
@ -102,6 +100,28 @@ public class BootstrapServiceRegistryImpl
|
||||||
public BootstrapServiceRegistryImpl(
|
public BootstrapServiceRegistryImpl(
|
||||||
ClassLoaderService classLoaderService,
|
ClassLoaderService classLoaderService,
|
||||||
LinkedHashSet<Integrator> providedIntegrators) {
|
LinkedHashSet<Integrator> providedIntegrators) {
|
||||||
|
this( true, classLoaderService, providedIntegrators );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a BootstrapServiceRegistryImpl.
|
||||||
|
*
|
||||||
|
* Do not use directly generally speaking. Use {@link org.hibernate.boot.registry.BootstrapServiceRegistryBuilder}
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* @param autoCloseRegistry See discussion on
|
||||||
|
* {@link org.hibernate.boot.registry.BootstrapServiceRegistryBuilder#disableAutoClose}
|
||||||
|
* @param classLoaderService The ClassLoaderService to use
|
||||||
|
* @param providedIntegrators The group of explicitly provided integrators
|
||||||
|
*
|
||||||
|
* @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder
|
||||||
|
*/
|
||||||
|
public BootstrapServiceRegistryImpl(
|
||||||
|
boolean autoCloseRegistry,
|
||||||
|
ClassLoaderService classLoaderService,
|
||||||
|
LinkedHashSet<Integrator> providedIntegrators) {
|
||||||
|
this.autoCloseRegistry = autoCloseRegistry;
|
||||||
|
|
||||||
this.classLoaderServiceBinding = new ServiceBinding<ClassLoaderService>(
|
this.classLoaderServiceBinding = new ServiceBinding<ClassLoaderService>(
|
||||||
this,
|
this,
|
||||||
ClassLoaderService.class,
|
ClassLoaderService.class,
|
||||||
|
@ -139,6 +159,31 @@ public class BootstrapServiceRegistryImpl
|
||||||
ClassLoaderService classLoaderService,
|
ClassLoaderService classLoaderService,
|
||||||
StrategySelector strategySelector,
|
StrategySelector strategySelector,
|
||||||
IntegratorService integratorService) {
|
IntegratorService integratorService) {
|
||||||
|
this( true, classLoaderService, strategySelector, integratorService );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a BootstrapServiceRegistryImpl.
|
||||||
|
*
|
||||||
|
* Do not use directly generally speaking. Use {@link org.hibernate.boot.registry.BootstrapServiceRegistryBuilder}
|
||||||
|
* instead.
|
||||||
|
*
|
||||||
|
* @param autoCloseRegistry See discussion on
|
||||||
|
* {@link org.hibernate.boot.registry.BootstrapServiceRegistryBuilder#disableAutoClose}
|
||||||
|
* @param classLoaderService The ClassLoaderService to use
|
||||||
|
* @param strategySelector The StrategySelector to use
|
||||||
|
* @param integratorService The IntegratorService to use
|
||||||
|
*
|
||||||
|
* @see org.hibernate.boot.registry.BootstrapServiceRegistryBuilder
|
||||||
|
*/
|
||||||
|
public BootstrapServiceRegistryImpl(
|
||||||
|
boolean autoCloseRegistry,
|
||||||
|
ClassLoaderService classLoaderService,
|
||||||
|
StrategySelector strategySelector,
|
||||||
|
IntegratorService integratorService) {
|
||||||
|
this.autoCloseRegistry = autoCloseRegistry;
|
||||||
|
|
||||||
this.classLoaderServiceBinding = new ServiceBinding<ClassLoaderService>(
|
this.classLoaderServiceBinding = new ServiceBinding<ClassLoaderService>(
|
||||||
this,
|
this,
|
||||||
ClassLoaderService.class,
|
ClassLoaderService.class,
|
||||||
|
@ -259,11 +304,19 @@ public class BootstrapServiceRegistryImpl
|
||||||
}
|
}
|
||||||
childRegistries.remove( child );
|
childRegistries.remove( child );
|
||||||
if ( childRegistries.isEmpty() ) {
|
if ( childRegistries.isEmpty() ) {
|
||||||
|
if ( autoCloseRegistry ) {
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
"Implicitly destroying Boot-strap registry on de-registration " +
|
"Implicitly destroying Boot-strap registry on de-registration " +
|
||||||
"of all child ServiceRegistries"
|
"of all child ServiceRegistries"
|
||||||
);
|
);
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
LOG.debug(
|
||||||
|
"Skipping implicitly destroying Boot-strap registry on de-registration " +
|
||||||
|
"of all child ServiceRegistries"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,30 @@ public class StandardServiceRegistryImpl extends AbstractServiceRegistryImpl imp
|
||||||
List<StandardServiceInitiator> serviceInitiators,
|
List<StandardServiceInitiator> serviceInitiators,
|
||||||
List<ProvidedService> providedServices,
|
List<ProvidedService> providedServices,
|
||||||
Map<?, ?> configurationValues) {
|
Map<?, ?> configurationValues) {
|
||||||
super( bootstrapServiceRegistry );
|
this( true, bootstrapServiceRegistry, serviceInitiators, providedServices, configurationValues );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a StandardServiceRegistryImpl. Should not be instantiated directly; use
|
||||||
|
* {@link org.hibernate.boot.registry.StandardServiceRegistryBuilder} instead
|
||||||
|
*
|
||||||
|
* @param autoCloseRegistry See discussion on
|
||||||
|
* {@link org.hibernate.boot.registry.StandardServiceRegistryBuilder#disableAutoClose}
|
||||||
|
* @param bootstrapServiceRegistry The bootstrap service registry.
|
||||||
|
* @param serviceInitiators Any StandardServiceInitiators provided by the user to the builder
|
||||||
|
* @param providedServices Any standard services provided directly to the builder
|
||||||
|
* @param configurationValues Configuration values
|
||||||
|
*
|
||||||
|
* @see org.hibernate.boot.registry.StandardServiceRegistryBuilder
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( {"unchecked"})
|
||||||
|
public StandardServiceRegistryImpl(
|
||||||
|
boolean autoCloseRegistry,
|
||||||
|
BootstrapServiceRegistry bootstrapServiceRegistry,
|
||||||
|
List<StandardServiceInitiator> serviceInitiators,
|
||||||
|
List<ProvidedService> providedServices,
|
||||||
|
Map<?, ?> configurationValues) {
|
||||||
|
super( bootstrapServiceRegistry, autoCloseRegistry );
|
||||||
|
|
||||||
this.configurationValues = configurationValues;
|
this.configurationValues = configurationValues;
|
||||||
|
|
||||||
|
|
|
@ -72,6 +72,7 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
// assume 20 services for initial sizing
|
// assume 20 services for initial sizing
|
||||||
private final List<ServiceBinding> serviceBindingList = CollectionHelper.arrayList( 20 );
|
private final List<ServiceBinding> serviceBindingList = CollectionHelper.arrayList( 20 );
|
||||||
|
|
||||||
|
private boolean autoCloseRegistry;
|
||||||
private Set<ServiceRegistryImplementor> childRegistries;
|
private Set<ServiceRegistryImplementor> childRegistries;
|
||||||
|
|
||||||
@SuppressWarnings( {"UnusedDeclaration"})
|
@SuppressWarnings( {"UnusedDeclaration"})
|
||||||
|
@ -79,20 +80,39 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
this( (ServiceRegistryImplementor) null );
|
this( (ServiceRegistryImplementor) null );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings( {"UnusedDeclaration"})
|
||||||
|
protected AbstractServiceRegistryImpl(boolean autoCloseRegistry) {
|
||||||
|
this( (ServiceRegistryImplementor) null, autoCloseRegistry );
|
||||||
|
}
|
||||||
|
|
||||||
protected AbstractServiceRegistryImpl(ServiceRegistryImplementor parent) {
|
protected AbstractServiceRegistryImpl(ServiceRegistryImplementor parent) {
|
||||||
|
this( parent, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractServiceRegistryImpl(
|
||||||
|
ServiceRegistryImplementor parent,
|
||||||
|
boolean autoCloseRegistry) {
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
|
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
|
||||||
|
|
||||||
|
this.autoCloseRegistry = autoCloseRegistry;
|
||||||
this.parent.registerChild( this );
|
this.parent.registerChild( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
public AbstractServiceRegistryImpl(BootstrapServiceRegistry bootstrapServiceRegistry) {
|
||||||
|
this( bootstrapServiceRegistry, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractServiceRegistryImpl(
|
||||||
|
BootstrapServiceRegistry bootstrapServiceRegistry,
|
||||||
|
boolean autoCloseRegistry) {
|
||||||
if ( ! ServiceRegistryImplementor.class.isInstance( bootstrapServiceRegistry ) ) {
|
if ( ! ServiceRegistryImplementor.class.isInstance( bootstrapServiceRegistry ) ) {
|
||||||
throw new IllegalArgumentException( "ServiceRegistry parent needs to implement ServiceRegistryImplementor" );
|
throw new IllegalArgumentException( "ServiceRegistry parent needs to implement ServiceRegistryImplementor" );
|
||||||
}
|
}
|
||||||
this.parent = (ServiceRegistryImplementor) bootstrapServiceRegistry;
|
this.parent = (ServiceRegistryImplementor) bootstrapServiceRegistry;
|
||||||
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
|
this.allowCrawling = ConfigurationHelper.getBoolean( ALLOW_CRAWLING, Environment.getProperties(), true );
|
||||||
|
|
||||||
|
this.autoCloseRegistry = autoCloseRegistry;
|
||||||
this.parent.registerChild( this );
|
this.parent.registerChild( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -382,11 +402,19 @@ public abstract class AbstractServiceRegistryImpl
|
||||||
}
|
}
|
||||||
childRegistries.remove( child );
|
childRegistries.remove( child );
|
||||||
if ( childRegistries.isEmpty() ) {
|
if ( childRegistries.isEmpty() ) {
|
||||||
|
if ( autoCloseRegistry ) {
|
||||||
log.debug(
|
log.debug(
|
||||||
"Implicitly destroying ServiceRegistry on de-registration " +
|
"Implicitly destroying ServiceRegistry on de-registration " +
|
||||||
"of all child ServiceRegistries"
|
"of all child ServiceRegistries"
|
||||||
);
|
);
|
||||||
destroy();
|
destroy();
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
log.debug(
|
||||||
|
"Skipping implicitly destroying ServiceRegistry on de-registration " +
|
||||||
|
"of all child ServiceRegistries"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,9 @@ import org.hibernate.exception.JDBCConnectionException;
|
||||||
import org.hibernate.service.Service;
|
import org.hibernate.service.Service;
|
||||||
import org.hibernate.service.internal.ProvidedService;
|
import org.hibernate.service.internal.ProvidedService;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.testing.TestForIssue;
|
import org.hibernate.testing.TestForIssue;
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
@ -55,6 +54,7 @@ public class ConnectionCreatorTest extends BaseUnitTestCase {
|
||||||
DriverConnectionCreator connectionCreator = new DriverConnectionCreator(
|
DriverConnectionCreator connectionCreator = new DriverConnectionCreator(
|
||||||
(Driver) Class.forName( "org.h2.Driver" ).newInstance(),
|
(Driver) Class.forName( "org.h2.Driver" ).newInstance(),
|
||||||
new StandardServiceRegistryImpl(
|
new StandardServiceRegistryImpl(
|
||||||
|
true,
|
||||||
new BootstrapServiceRegistryImpl(),
|
new BootstrapServiceRegistryImpl(),
|
||||||
Collections.<StandardServiceInitiator>emptyList(),
|
Collections.<StandardServiceInitiator>emptyList(),
|
||||||
Collections.<ProvidedService>emptyList(),
|
Collections.<ProvidedService>emptyList(),
|
||||||
|
|
Loading…
Reference in New Issue