DATACMNS-809 - Polishing.

Removed DefaultPersistentPropertyAccessorFactory as it only delegates to the class generating one. Tweaked AbstractMappingContext to actually use the latter in the first place. Introduced BeanWrapperPropertyAccessorFactory to implement the default behavior of using a BeanWrapper and initialize BasicPersistentEntity to avoid a null clause in getPersistentPropertyAccessor(…).

Removed getPersistentPropertyAccessorFactory and rather rely on ReflectionTestUtils in tests to avoid additional API being exposed.

Original pull request: #159.
This commit is contained in:
Oliver Gierke
2016-05-03 16:44:38 +02:00
parent defc3c7874
commit 38a41139fc
7 changed files with 41 additions and 46 deletions

View File

@@ -37,9 +37,10 @@ import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PropertyPath;
import org.springframework.data.mapping.model.DefaultPersistentPropertyAccessorFactory;
import org.springframework.data.mapping.model.ClassGeneratingPropertyAccessorFactory;
import org.springframework.data.mapping.model.MappingException;
import org.springframework.data.mapping.model.MutablePersistentEntity;
import org.springframework.data.mapping.model.PersistentPropertyAccessorFactory;
import org.springframework.data.mapping.model.SimpleTypeHolder;
import org.springframework.data.util.ClassTypeInformation;
import org.springframework.data.util.TypeInformation;
@@ -69,7 +70,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
implements MappingContext<E, P>, ApplicationEventPublisherAware, InitializingBean {
private final Map<TypeInformation<?>, E> persistentEntities = new HashMap<TypeInformation<?>, E>();
private final DefaultPersistentPropertyAccessorFactory persistentPropertyAccessorFactory = new DefaultPersistentPropertyAccessorFactory();
private final PersistentPropertyAccessorFactory persistentPropertyAccessorFactory = new ClassGeneratingPropertyAccessorFactory();
private ApplicationEventPublisher applicationEventPublisher;
@@ -126,6 +127,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
* @see org.springframework.data.mapping.model.MappingContext#getPersistentEntities()
*/
public Collection<E> getPersistentEntities() {
try {
read.lock();
return Collections.unmodifiableSet(new HashSet<E>(persistentEntities.values()));
@@ -322,6 +324,7 @@ public abstract class AbstractMappingContext<E extends MutablePersistentEntity<?
if (persistentPropertyAccessorFactory.isSupported(entity)) {
entity.setPersistentPropertyAccessorFactory(persistentPropertyAccessorFactory);
}
} catch (MappingException e) {
persistentEntities.remove(typeInformation);
throw e;

View File

@@ -69,7 +69,6 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
private P idProperty;
private P versionProperty;
private PersistentPropertyAccessorFactory propertyAccessorFactory;
/**
@@ -102,6 +101,7 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
this.propertyCache = new HashMap<String, P>();
this.annotationCache = new HashMap<Class<? extends Annotation>, Annotation>();
this.propertyAccessorFactory = BeanWrapperPropertyAccessorFactory.INSTANCE;
}
/*
@@ -391,7 +391,8 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
}
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.model.MutablePersistentEntity#setPersistentPropertyAccessorFactory(org.springframework.data.mapping.model.PersistentPropertyAccessorFactory)
*/
@Override
@@ -399,24 +400,16 @@ public class BasicPersistentEntity<T, P extends PersistentProperty<P>> implement
this.propertyAccessorFactory = factory;
}
public PersistentPropertyAccessorFactory getPropertyAccessorFactory() {
return propertyAccessorFactory;
}
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentEntity#getPropertyAccessor(java.lang.Object)
*/
* (non-Javadoc)
* @see org.springframework.data.mapping.PersistentEntity#getPropertyAccessor(java.lang.Object)
*/
@Override
public PersistentPropertyAccessor getPropertyAccessor(Object bean) {
Assert.notNull(bean, "Target bean must not be null!");
Assert.isTrue(getType().isInstance(bean), "Target bean is not of type of the persistent entity!");
if (propertyAccessorFactory == null) {
return new BeanWrapper<Object>(bean);
}
return propertyAccessorFactory.getPropertyAccessor(this, bean);
}

View File

@@ -19,31 +19,29 @@ import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentPropertyAccessor;
/**
* Default implementation of {@link PersistentPropertyAccessorFactory}. Accessors can access bean properties either via
* reflection or use generated classes with direct field/method access.
*
* @author Mark Paluch
* PersistentPropertyAccessorFactory that uses a {@link BeanWrapper}.
*
* @author Oliver Gierke
* @since 1.13
*/
public class DefaultPersistentPropertyAccessorFactory implements PersistentPropertyAccessorFactory {
enum BeanWrapperPropertyAccessorFactory implements PersistentPropertyAccessorFactory {
private final ClassGeneratingPropertyAccessorFactory classGeneratingPropertyAccessorFactory = new ClassGeneratingPropertyAccessorFactory();
INSTANCE;
/*
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.model.PersistentPropertyAccessorFactory#getPropertyAccessor(org.springframework.data.mapping.PersistentEntity, java.lang.Object)
*/
@Override
public PersistentPropertyAccessor getPropertyAccessor(PersistentEntity<?, ?> entity, Object bean) {
return classGeneratingPropertyAccessorFactory.getPropertyAccessor(entity, bean);
return new BeanWrapper<Object>(bean);
}
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.model.PersistentPropertyAccessorFactory#isSupported(org.springframework.data.mapping.PersistentEntity)
*/
@Override
public boolean isSupported(PersistentEntity<?, ?> entity) {
return classGeneratingPropertyAccessorFactory.isSupported(entity);
return true;
}
}

View File

@@ -59,7 +59,7 @@ import org.springframework.util.ReflectionUtils;
* @author Oliver Gierke
* @since 1.13
*/
class ClassGeneratingPropertyAccessorFactory implements PersistentPropertyAccessorFactory {
public class ClassGeneratingPropertyAccessorFactory implements PersistentPropertyAccessorFactory {
private static final boolean IS_JAVA_7_OR_BETTER = org.springframework.util.ClassUtils
.isPresent("java.lang.invoke.MethodHandle", ClassGeneratingPropertyAccessorFactory.class.getClassLoader());
@@ -67,7 +67,8 @@ class ClassGeneratingPropertyAccessorFactory implements PersistentPropertyAccess
private volatile Map<TypeInformation<?>, Class<PersistentPropertyAccessor>> propertyAccessorClasses = new HashMap<TypeInformation<?>, Class<PersistentPropertyAccessor>>(
32);
/* (non-Javadoc)
/*
* (non-Javadoc)
* @see org.springframework.data.mapping.model.PersistentPropertyAccessorFactory#getPropertyAccessor(org.springframework.data.mapping.PersistentEntity, java.lang.Object)
*/
@Override
@@ -86,24 +87,18 @@ class ClassGeneratingPropertyAccessorFactory implements PersistentPropertyAccess
}
}
/* (non-Javadoc)
* @see org.springframework.data.mapping.model.PersistentPropertyAccessorFactory#isSupported(org.springframework.data.mapping.PersistentEntity)
*/
@Override
public boolean isSupported(PersistentEntity<?, ?> entity) {
Assert.notNull(entity, "PersistentEntity must not be null!");
return canGenerateAccessorClass(entity);
}
/**
* Checks whether an accessor class can be generated.
*
* @param entity
* @return {@literal true} if the runtime is equal or greater to Java 1.7, property name hash codes are unique and the
* type has a class loader we can use to re-inject types.
* @see PersistentPropertyAccessorFactory#isSupported(PersistentEntity)
*/
public static boolean canGenerateAccessorClass(PersistentEntity<?, ?> entity) {
@Override
public boolean isSupported(PersistentEntity<?, ?> entity) {
Assert.notNull(entity, "PersistentEntity must not be null!");
if (!IS_JAVA_7_OR_BETTER) {
return false;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2016 by the original author(s).
* Copyright 2011-2016 by the original author(s).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ public interface MutablePersistentEntity<T, P extends PersistentProperty<P>> ext
* Sets the {@link PersistentPropertyAccessorFactory} for the entity. A {@link PersistentPropertyAccessorFactory}
* creates {@link PersistentPropertyAccessor}s for instances of this entity.
*
* @param factory
* @param factory must not be {@literal null}.
*/
void setPersistentPropertyAccessorFactory(PersistentPropertyAccessorFactory factory);
}