Move test.type.contributor and implement support for constructor injection of TypeBootstrapContext

This commit is contained in:
Christian Beikov 2021-07-29 18:43:32 +02:00
parent d3810b8f7a
commit 95a34e2895
9 changed files with 102 additions and 23 deletions

View File

@ -0,0 +1,61 @@
/*
* 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.boot.model;
import java.lang.reflect.Constructor;
import java.util.Map;
import org.hibernate.MappingException;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.hibernate.type.spi.TypeBootstrapContext;
import org.hibernate.type.spi.TypeConfiguration;
/**
* @author Christian Beikov
*/
public class TypeBeanInstanceProducer implements BeanInstanceProducer, TypeBootstrapContext {
private final TypeConfiguration typeConfiguration;
public TypeBeanInstanceProducer(TypeConfiguration typeConfiguration) {
this.typeConfiguration = typeConfiguration;
}
@Override
public <B> B produceBeanInstance(Class<B> beanType) {
try {
final B type;
final Constructor<B> bootstrapContextAwareTypeConstructor = ReflectHelper.getConstructor(
beanType,
TypeBootstrapContext.class
);
if ( bootstrapContextAwareTypeConstructor != null ) {
type = bootstrapContextAwareTypeConstructor.newInstance( this );
}
else {
type = beanType.newInstance();
}
return type;
}
catch (Exception e) {
throw new MappingException( "Could not instantiate Type: " + beanType.getName(), e );
}
}
@Override
public <B> B produceBeanInstance(String name, Class<B> beanType) {
return produceBeanInstance( beanType );
}
@Override
@SuppressWarnings("unchecked")
public Map<String, Object> getConfigurationSettings() {
return typeConfiguration.getServiceRegistry().getService( ConfigurationService.class ).getSettings();
}
}

View File

@ -22,6 +22,7 @@ import org.hibernate.internal.util.collections.CollectionHelper;
import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.BasicValue;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.type.BasicType; import org.hibernate.type.BasicType;
@ -135,7 +136,7 @@ public class TypeDefinition implements Serializable {
JdbcTypeDescriptorIndicators indicators, JdbcTypeDescriptorIndicators indicators,
MetadataBuildingContext context) { MetadataBuildingContext context) {
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration(); final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
final TypeBeanInstanceProducer instanceProducer = new TypeBeanInstanceProducer( typeConfiguration );
final boolean isKnownType = Type.class.isAssignableFrom( typeImplementorClass ) final boolean isKnownType = Type.class.isAssignableFrom( typeImplementorClass )
|| UserType.class.isAssignableFrom( typeImplementorClass ); || UserType.class.isAssignableFrom( typeImplementorClass );
@ -146,13 +147,13 @@ public class TypeDefinition implements Serializable {
typeBean = context.getBootstrapContext() typeBean = context.getBootstrapContext()
.getServiceRegistry() .getServiceRegistry()
.getService( ManagedBeanRegistry.class ) .getService( ManagedBeanRegistry.class )
.getBean( name, typeImplementorClass ); .getBean( name, typeImplementorClass, instanceProducer );
} }
else { else {
typeBean = context.getBootstrapContext() typeBean = context.getBootstrapContext()
.getServiceRegistry() .getServiceRegistry()
.getService( ManagedBeanRegistry.class ) .getService( ManagedBeanRegistry.class )
.getBean( typeImplementorClass ); .getBean( typeImplementorClass, instanceProducer );
} }
final Object typeInstance = typeBean.getBeanInstance(); final Object typeInstance = typeBean.getBeanInstance();

View File

@ -12,6 +12,7 @@ import java.util.Map;
import org.hibernate.resource.beans.container.spi.BeanContainer; import org.hibernate.resource.beans.container.spi.BeanContainer;
import org.hibernate.resource.beans.container.spi.ContainedBean; import org.hibernate.resource.beans.container.spi.ContainedBean;
import org.hibernate.resource.beans.container.spi.FallbackContainedBean; import org.hibernate.resource.beans.container.spi.FallbackContainedBean;
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.service.spi.Stoppable; import org.hibernate.service.spi.Stoppable;
@ -48,6 +49,11 @@ public class ManagedBeanRegistryImpl implements ManagedBeanRegistry, BeanContain
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> ManagedBean<T> getBean(Class<T> beanClass) { public <T> ManagedBean<T> getBean(Class<T> beanClass) {
return getBean( beanClass, FallbackBeanInstanceProducer.INSTANCE );
}
@Override
public <T> ManagedBean<T> getBean(Class<T> beanClass, BeanInstanceProducer fallbackBeanInstanceProducer) {
final ManagedBean existing = registrations.get( beanClass.getName() ); final ManagedBean existing = registrations.get( beanClass.getName() );
if ( existing != null ) { if ( existing != null ) {
return existing; return existing;
@ -55,13 +61,13 @@ public class ManagedBeanRegistryImpl implements ManagedBeanRegistry, BeanContain
final ManagedBean bean; final ManagedBean bean;
if ( beanContainer == null ) { if ( beanContainer == null ) {
bean = new FallbackContainedBean( beanClass, FallbackBeanInstanceProducer.INSTANCE ); bean = new FallbackContainedBean( beanClass, fallbackBeanInstanceProducer );
} }
else { else {
final ContainedBean<T> containedBean = beanContainer.getBean( final ContainedBean<T> containedBean = beanContainer.getBean(
beanClass, beanClass,
this, this,
FallbackBeanInstanceProducer.INSTANCE fallbackBeanInstanceProducer
); );
if ( containedBean instanceof ManagedBean ) { if ( containedBean instanceof ManagedBean ) {
@ -78,8 +84,16 @@ public class ManagedBeanRegistryImpl implements ManagedBeanRegistry, BeanContain
} }
@Override @Override
@SuppressWarnings("unchecked")
public <T> ManagedBean<T> getBean(String beanName, Class<T> beanContract) { public <T> ManagedBean<T> getBean(String beanName, Class<T> beanContract) {
return getBean( beanName, beanContract, FallbackBeanInstanceProducer.INSTANCE );
}
@Override
@SuppressWarnings("unchecked")
public <T> ManagedBean<T> getBean(
String beanName,
Class<T> beanContract,
BeanInstanceProducer fallbackBeanInstanceProducer) {
final String key = beanContract.getName() + ':' + beanName; final String key = beanContract.getName() + ':' + beanName;
final ManagedBean existing = registrations.get( key ); final ManagedBean existing = registrations.get( key );
@ -89,14 +103,14 @@ public class ManagedBeanRegistryImpl implements ManagedBeanRegistry, BeanContain
final ManagedBean bean; final ManagedBean bean;
if ( beanContainer == null ) { if ( beanContainer == null ) {
bean = new FallbackContainedBean( beanName, beanContract, FallbackBeanInstanceProducer.INSTANCE ); bean = new FallbackContainedBean( beanName, beanContract, fallbackBeanInstanceProducer );
} }
else { else {
final ContainedBean<T> containedBean = beanContainer.getBean( final ContainedBean<T> containedBean = beanContainer.getBean(
beanName, beanName,
beanContract, beanContract,
this, this,
FallbackBeanInstanceProducer.INSTANCE fallbackBeanInstanceProducer
); );
if ( containedBean instanceof ManagedBean ) { if ( containedBean instanceof ManagedBean ) {

View File

@ -28,6 +28,19 @@ public interface ManagedBeanRegistry extends Service {
*/ */
<T> ManagedBean<T> getBean(String beanName, Class<T> beanContract); <T> ManagedBean<T> getBean(String beanName, Class<T> beanContract);
/**
* Get a bean reference by class with an explicit fallback bean instance producer.
*/
<T> ManagedBean<T> getBean(Class<T> beanContract, BeanInstanceProducer fallbackBeanInstanceProducer);
/**
* Get a bean reference by name and contract with an explicit fallback bean instance producer.
*/
<T> ManagedBean<T> getBean(
String beanName,
Class<T> beanContract,
BeanInstanceProducer fallbackBeanInstanceProducer);
/** /**
* Get a reference to the underlying BeanContainer. May return {@code null} * Get a reference to the underlying BeanContainer. May return {@code null}
* indicating that no back-end container has been configured * indicating that no back-end container has been configured

View File

@ -1,4 +1,4 @@
package org.hibernate.test.type.contributor; package org.hibernate.orm.test.type.contributor;
import java.util.ArrayList; import java.util.ArrayList;

View File

@ -1,4 +1,4 @@
package org.hibernate.test.type.contributor; package org.hibernate.orm.test.type.contributor;
import java.util.Map; import java.util.Map;

View File

@ -4,16 +4,13 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/ */
package org.hibernate.test.type.contributor; package org.hibernate.orm.test.type.contributor;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import org.hibernate.Session;
import org.hibernate.annotations.Type; import org.hibernate.annotations.Type;
import org.hibernate.boot.spi.MetadataBuilderContributor; import org.hibernate.boot.spi.MetadataBuilderContributor;
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl; import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;

View File

@ -1,4 +1,4 @@
package org.hibernate.test.type.contributor; package org.hibernate.orm.test.type.contributor;
import java.util.Arrays; import java.util.Arrays;

View File

@ -4,23 +4,16 @@
* License: GNU Lesser General Public License (LGPL), version 2.1 or later. * 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>. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/ */
package org.hibernate.test.type.contributor; package org.hibernate.orm.test.type.contributor;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.transaction.Transactional;
import org.hibernate.Session;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef; import org.hibernate.annotations.TypeDef;
import org.hibernate.boot.spi.MetadataBuilderContributor;
import org.hibernate.engine.spi.EntityEntry;
import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.hibernate.persister.entity.EntityPersister; import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.query.Query; import org.hibernate.query.Query;