HHH-10669 - Allow to add SF-scoped services through a ServiceContributor

This commit is contained in:
Steve Ebersole 2016-05-05 16:07:35 -05:00
parent 60dd63536e
commit 5e30247c6f
8 changed files with 147 additions and 7 deletions

View File

@ -0,0 +1,84 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.service.internal;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.Service;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceInitiator;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistryBuilder;
/**
* @author Steve Ebersole
*/
public class SessionFactoryServiceRegistryBuilderImpl implements SessionFactoryServiceRegistryBuilder {
private final ServiceRegistryImplementor parent;
private final List<SessionFactoryServiceInitiator> initiators = standardInitiatorList();
private final List<ProvidedService> providedServices = new ArrayList<>();
public SessionFactoryServiceRegistryBuilderImpl(ServiceRegistryImplementor parent) {
this.parent = parent;
}
/**
* Used from the {@link #initiators} variable initializer
*
* @return List of standard initiators
*/
private static List<SessionFactoryServiceInitiator> standardInitiatorList() {
final List<SessionFactoryServiceInitiator> initiators = new ArrayList<>();
initiators.addAll( StandardSessionFactoryServiceInitiators.LIST );
return initiators;
}
/**
* Adds a service initiator.
*
* @param initiator The initiator to be added
*
* @return this, for method chaining
*/
@Override
@SuppressWarnings( {"UnusedDeclaration"})
public SessionFactoryServiceRegistryBuilder addInitiator(SessionFactoryServiceInitiator initiator) {
initiators.add( initiator );
return this;
}
/**
* Adds a user-provided service.
*
* @param serviceRole The role of the service being added
* @param service The service implementation
*
* @return this, for method chaining
*/
@Override
@SuppressWarnings( {"unchecked"})
public SessionFactoryServiceRegistryBuilder addService(final Class serviceRole, final Service service) {
providedServices.add( new ProvidedService( serviceRole, service ) );
return this;
}
public SessionFactoryServiceRegistry buildSessionFactoryServiceRegistry(
SessionFactoryImplementor sessionFactory,
SessionFactoryOptions options) {
return new SessionFactoryServiceRegistryImpl(
parent,
initiators,
providedServices,
sessionFactory,
options
);
}
}

View File

@ -6,9 +6,12 @@
*/ */
package org.hibernate.service.internal; package org.hibernate.service.internal;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.spi.ServiceRegistryImplementor; import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.service.spi.SessionFactoryServiceContributor;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistryFactory; import org.hibernate.service.spi.SessionFactoryServiceRegistryFactory;
/** /**
@ -25,9 +28,16 @@ public class SessionFactoryServiceRegistryFactoryImpl implements SessionFactoryS
} }
@Override @Override
public SessionFactoryServiceRegistryImpl buildServiceRegistry( public SessionFactoryServiceRegistry buildServiceRegistry(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
SessionFactoryOptions options) { SessionFactoryOptions options) {
return new SessionFactoryServiceRegistryImpl( theBasicServiceRegistry, sessionFactory, options ); final ClassLoaderService cls = options.getServiceRegistry().getService( ClassLoaderService.class );
final SessionFactoryServiceRegistryBuilderImpl builder = new SessionFactoryServiceRegistryBuilderImpl( theBasicServiceRegistry );
for ( SessionFactoryServiceContributor contributor : cls.loadJavaServices( SessionFactoryServiceContributor.class ) ) {
contributor.contribute( builder );
}
return builder.buildSessionFactoryServiceRegistry( sessionFactory, options );
} }
} }

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.service.internal; package org.hibernate.service.internal;
import java.util.List;
import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.Service; import org.hibernate.service.Service;
@ -26,6 +28,8 @@ public class SessionFactoryServiceRegistryImpl extends AbstractServiceRegistryIm
@SuppressWarnings( {"unchecked"}) @SuppressWarnings( {"unchecked"})
public SessionFactoryServiceRegistryImpl( public SessionFactoryServiceRegistryImpl(
ServiceRegistryImplementor parent, ServiceRegistryImplementor parent,
List<SessionFactoryServiceInitiator> initiators,
List<ProvidedService> providedServices,
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
SessionFactoryOptions sessionFactoryOptions) { SessionFactoryOptions sessionFactoryOptions) {
super( parent ); super( parent );
@ -34,10 +38,15 @@ public class SessionFactoryServiceRegistryImpl extends AbstractServiceRegistryIm
this.sessionFactoryOptions = sessionFactoryOptions; this.sessionFactoryOptions = sessionFactoryOptions;
// for now, just use the standard initiator list // for now, just use the standard initiator list
for ( SessionFactoryServiceInitiator initiator : StandardSessionFactoryServiceInitiators.LIST ) { for ( SessionFactoryServiceInitiator initiator : initiators ) {
// create the bindings up front to help identify to which registry services belong // create the bindings up front to help identify to which registry services belong
createServiceBinding( initiator ); createServiceBinding( initiator );
} }
for ( ProvidedService providedService : providedServices ) {
createServiceBinding( providedService );
}
} }
@Override @Override

View File

@ -26,7 +26,7 @@ public class StandardSessionFactoryServiceInitiators {
public static List<SessionFactoryServiceInitiator> LIST = buildStandardServiceInitiatorList(); public static List<SessionFactoryServiceInitiator> LIST = buildStandardServiceInitiatorList();
private static List<SessionFactoryServiceInitiator> buildStandardServiceInitiatorList() { private static List<SessionFactoryServiceInitiator> buildStandardServiceInitiatorList() {
final List<SessionFactoryServiceInitiator> serviceInitiators = new ArrayList<SessionFactoryServiceInitiator>(); final List<SessionFactoryServiceInitiator> serviceInitiators = new ArrayList<>();
serviceInitiators.add( EventListenerServiceInitiator.INSTANCE ); serviceInitiators.add( EventListenerServiceInitiator.INSTANCE );
serviceInitiators.add( StatisticsInitiator.INSTANCE ); serviceInitiators.add( StatisticsInitiator.INSTANCE );

View File

@ -19,5 +19,5 @@ public interface ServiceContributor {
* *
* @param serviceRegistryBuilder The builder to which services (or initiators) should be contributed. * @param serviceRegistryBuilder The builder to which services (or initiators) should be contributed.
*/ */
public void contribute(StandardServiceRegistryBuilder serviceRegistryBuilder); void contribute(StandardServiceRegistryBuilder serviceRegistryBuilder);
} }

View File

@ -0,0 +1,19 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.service.spi;
/**
* @author Steve Ebersole
*/
public interface SessionFactoryServiceContributor {
/**
* Contribute services to the indicated registry builder.
*
* @param serviceRegistryBuilder The builder to which services (or initiators) should be contributed.
*/
void contribute(SessionFactoryServiceRegistryBuilder serviceRegistryBuilder);
}

View File

@ -0,0 +1,19 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.service.spi;
import org.hibernate.service.Service;
/**
* @author Steve Ebersole
*/
public interface SessionFactoryServiceRegistryBuilder {
SessionFactoryServiceRegistryBuilder addInitiator(SessionFactoryServiceInitiator initiator);
@SuppressWarnings( {"unchecked"})
SessionFactoryServiceRegistryBuilder addService(Class serviceRole, Service service);
}

View File

@ -9,7 +9,6 @@ package org.hibernate.service.spi;
import org.hibernate.boot.spi.SessionFactoryOptions; import org.hibernate.boot.spi.SessionFactoryOptions;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.service.Service; import org.hibernate.service.Service;
import org.hibernate.service.internal.SessionFactoryServiceRegistryImpl;
/** /**
* Contract for builder of {@link SessionFactoryServiceRegistry} instances. * Contract for builder of {@link SessionFactoryServiceRegistry} instances.
@ -29,7 +28,7 @@ public interface SessionFactoryServiceRegistryFactory extends Service {
* *
* @return The registry * @return The registry
*/ */
public SessionFactoryServiceRegistryImpl buildServiceRegistry( SessionFactoryServiceRegistry buildServiceRegistry(
SessionFactoryImplementor sessionFactory, SessionFactoryImplementor sessionFactory,
SessionFactoryOptions sessionFactoryOptions); SessionFactoryOptions sessionFactoryOptions);