📄 persistenceannotationbeanpostprocessor.java
字号:
}
return metadata;
}
}
private void addIfPresent(List<AnnotatedMember> metadata, Member member) {
AnnotatedElement ae = (AnnotatedElement) member;
PersistenceContext pc = ae.getAnnotation(PersistenceContext.class);
PersistenceUnit pu = ae.getAnnotation(PersistenceUnit.class);
if (pc != null) {
if (pu != null) {
throw new IllegalStateException(
"Method may only be annotated with either @PersistenceContext or @PersistenceUnit, not both");
}
if (member instanceof Method && ((Method) member).getParameterTypes().length != 1) {
throw new IllegalStateException("PersistenceContext annotation requires a single-arg method: " + member);
}
Properties properties = null;
PersistenceProperty[] pps = pc.properties();
if (!ObjectUtils.isEmpty(pps)) {
properties = new Properties();
for (int i = 0; i < pps.length; i++) {
PersistenceProperty pp = pps[i];
properties.setProperty(pp.name(), pp.value());
}
}
metadata.add(new AnnotatedMember(member, pc.unitName(), pc.type(), properties));
}
else if (pu != null) {
if (member instanceof Method && ((Method) member).getParameterTypes().length != 1) {
throw new IllegalStateException("PersistenceUnit annotation requires a single-arg method: " + member);
}
metadata.add(new AnnotatedMember(member, pu.unitName()));
}
}
/**
* Return a specified persistence unit for the given unit name,
* as defined through the "persistenceUnits" map.
* @param unitName the name of the persistence unit
* @return the corresponding EntityManagerFactory,
* or <code>null</code> if none found
* @see #setPersistenceUnits
*/
protected EntityManagerFactory getPersistenceUnit(String unitName) {
if (this.persistenceUnits != null) {
String unitNameForLookup = (unitName != null ? unitName : "");
if ("".equals(unitNameForLookup)) {
unitNameForLookup = this.defaultPersistenceUnitName;
}
String jndiName = this.persistenceUnits.get(unitNameForLookup);
if (jndiName == null && "".equals(unitNameForLookup) && this.persistenceUnits.size() == 1) {
jndiName = this.persistenceUnits.values().iterator().next();
}
if (jndiName != null) {
try {
return (EntityManagerFactory) lookup(jndiName, EntityManagerFactory.class);
}
catch (NamingException ex) {
throw new IllegalStateException("Could not obtain EntityManagerFactory [" + jndiName + "] from JNDI", ex);
}
}
}
return null;
}
/**
* Return a specified persistence context for the given unit name, as defined
* through the "persistenceContexts" (or "extendedPersistenceContexts") map.
* @param unitName the name of the persistence unit
* @param extended whether to obtain an extended persistence context
* @return the corresponding EntityManager, or <code>null</code> if none found
* @see #setPersistenceContexts
* @see #setExtendedPersistenceContexts
*/
protected EntityManager getPersistenceContext(String unitName, boolean extended) {
Map<String, String> contexts = (extended ? this.extendedPersistenceContexts : this.persistenceContexts);
if (contexts != null) {
String unitNameForLookup = (unitName != null ? unitName : "");
if ("".equals(unitNameForLookup)) {
unitNameForLookup = this.defaultPersistenceUnitName;
}
String jndiName = contexts.get(unitNameForLookup);
if (jndiName == null && "".equals(unitNameForLookup) && contexts.size() == 1) {
jndiName = contexts.values().iterator().next();
}
if (jndiName != null) {
try {
return (EntityManager) lookup(jndiName, EntityManager.class);
}
catch (NamingException ex) {
throw new IllegalStateException("Could not obtain EntityManager [" + jndiName + "] from JNDI", ex);
}
}
}
return null;
}
/**
* Find an EntityManagerFactory with the given name in the current Spring
* application context, falling back to a single default EntityManagerFactory
* (if any) in case of no unit name specified.
* @param unitName the name of the persistence unit (may be <code>null</code> or empty)
* @return the EntityManagerFactory
* @throws NoSuchBeanDefinitionException if there is no such EntityManagerFactory in the context
*/
protected EntityManagerFactory findEntityManagerFactory(String unitName) throws NoSuchBeanDefinitionException {
if (this.beanFactory == null) {
throw new IllegalStateException("ListableBeanFactory required for EntityManagerFactory lookup");
}
String unitNameForLookup = (unitName != null ? unitName : "");
if ("".equals(unitNameForLookup)) {
unitNameForLookup = this.defaultPersistenceUnitName;
}
if (!"".equals(unitNameForLookup)) {
return findNamedEntityManagerFactory(unitNameForLookup);
}
else {
return findDefaultEntityManagerFactory();
}
}
/**
* Find an EntityManagerFactory with the given name in the current
* Spring application context.
* @param unitName the name of the persistence unit (never empty)
* @return the EntityManagerFactory
* @throws NoSuchBeanDefinitionException if there is no such EntityManagerFactory in the context
*/
protected EntityManagerFactory findNamedEntityManagerFactory(String unitName)
throws NoSuchBeanDefinitionException {
return EntityManagerFactoryUtils.findEntityManagerFactory(this.beanFactory, unitName);
}
/**
* Find a single default EntityManagerFactory in the Spring application context.
* @return the default EntityManagerFactory
* @throws NoSuchBeanDefinitionException if there is no single EntityManagerFactory in the context
*/
protected EntityManagerFactory findDefaultEntityManagerFactory() {
return (EntityManagerFactory) BeanFactoryUtils.beanOfTypeIncludingAncestors(
this.beanFactory, EntityManagerFactory.class);
}
/**
* Class representing injection information about an annotated field
* or setter method.
*/
private class AnnotatedMember {
private final Member member;
private final String unitName;
private final PersistenceContextType type;
private final Properties properties;
public AnnotatedMember(Member member, String unitName) {
this(member, unitName, null, null);
}
public AnnotatedMember(Member member, String unitName, PersistenceContextType type, Properties properties) {
this.member = member;
this.unitName = unitName;
this.type = type;
this.properties = properties;
// Validate member type
Class<?> memberType = getMemberType();
if (!(EntityManagerFactory.class.isAssignableFrom(memberType) ||
EntityManager.class.isAssignableFrom(memberType))) {
throw new IllegalArgumentException("Cannot inject " + member + ": not a supported JPA type");
}
}
public void inject(Object instance) {
Object value = resolve();
try {
if (!Modifier.isPublic(this.member.getModifiers()) ||
!Modifier.isPublic(this.member.getDeclaringClass().getModifiers())) {
((AccessibleObject) this.member).setAccessible(true);
}
if (this.member instanceof Field) {
((Field) this.member).set(instance, value);
}
else if (this.member instanceof Method) {
((Method) this.member).invoke(instance, value);
}
else {
throw new IllegalArgumentException("Cannot inject unknown AccessibleObject type " + this.member);
}
}
catch (IllegalAccessException ex) {
throw new IllegalArgumentException("Cannot inject member " + this.member, ex);
}
catch (InvocationTargetException ex) {
// Method threw an exception
throw new IllegalArgumentException("Attempt to inject setter method " + this.member +
" resulted in an exception", ex);
}
}
/**
* Return the type of the member, whether it's a field or a method.
*/
public Class<?> getMemberType() {
if (this.member instanceof Field) {
return ((Field) member).getType();
}
else if (this.member instanceof Method) {
Method setter = (Method) this.member;
if (setter.getParameterTypes().length != 1) {
throw new IllegalArgumentException(
"Supposed setter [" + this.member + "] must have 1 argument, not " +
setter.getParameterTypes().length);
}
return setter.getParameterTypes()[0];
}
else {
throw new IllegalArgumentException(
"Unknown AccessibleObject type [" + this.member.getClass() +
"]; can only inject setter methods and fields");
}
}
/**
* Resolve the object against the application context.
*/
private Object resolve() {
// Resolves to EntityManagerFactory or EntityManager.
if (EntityManagerFactory.class.isAssignableFrom(getMemberType())) {
EntityManagerFactory emf = resolveEntityManagerFactory();
if (!getMemberType().isInstance(emf)) {
throw new IllegalArgumentException("Cannot inject [" + this.member +
"] with EntityManagerFactory [" + emf + "]: type mismatch");
}
return emf;
}
else {
// OK, so we need an EntityManager...
EntityManager em = (this.type == PersistenceContextType.EXTENDED ?
resolveExtendedEntityManager() : resolveEntityManager());
if (!getMemberType().isInstance(em)) {
throw new IllegalArgumentException("Cannot inject [" + this.member +
"] with EntityManager [" + em + "]: type mismatch");
}
return em;
}
}
private EntityManagerFactory resolveEntityManagerFactory() {
// Obtain EntityManagerFactory from JNDI?
EntityManagerFactory emf = getPersistenceUnit(this.unitName);
if (emf == null) {
// Need to search for EntityManagerFactory beans.
emf = findEntityManagerFactory(this.unitName);
}
return emf;
}
private EntityManager resolveEntityManager() {
// Obtain EntityManager reference from JNDI?
EntityManager em = getPersistenceContext(this.unitName, false);
if (em == null) {
// No pre-built EntityManager found -> build one based on factory.
// Obtain EntityManagerFactory from JNDI?
EntityManagerFactory emf = getPersistenceUnit(this.unitName);
if (emf == null) {
// Need to search for EntityManagerFactory beans.
emf = findEntityManagerFactory(this.unitName);
}
// Inject a shared transactional EntityManager proxy.
if (emf instanceof EntityManagerFactoryInfo &&
!EntityManager.class.equals(((EntityManagerFactoryInfo) emf).getEntityManagerInterface())) {
// Create EntityManager based on the info's vendor-specific type
// (which might be more specific than the field's type).
em = SharedEntityManagerCreator.createSharedEntityManager(emf, this.properties);
}
else {
// Create EntityManager based on the field's type.
em = SharedEntityManagerCreator.createSharedEntityManager(emf, this.properties, getMemberType());
}
}
return em;
}
private EntityManager resolveExtendedEntityManager() {
// Obtain EntityManager reference from JNDI?
EntityManager em = getPersistenceContext(this.unitName, true);
if (em == null) {
// No pre-built EntityManager found -> build one based on factory.
// Obtain EntityManagerFactory from JNDI?
EntityManagerFactory emf = getPersistenceUnit(this.unitName);
if (emf == null) {
// Need to search for EntityManagerFactory beans.
emf = findEntityManagerFactory(this.unitName);
}
// Inject a container-managed extended EntityManager.
em = ExtendedEntityManagerCreator.createContainerManagedEntityManager(emf, this.properties);
}
return em;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -