Browse Source

Shared empty InjectionMetadata/LifecycleMetadata instance

Closes gh-22570
pull/26676/head
Juergen Hoeller 7 years ago
parent
commit
c0ddaae5c0
  1. 4
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java
  2. 23
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java
  3. 46
      spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java
  4. 4
      spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java
  5. 5
      spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java

4
spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

@ -443,7 +443,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean @@ -443,7 +443,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return new InjectionMetadata(clazz, Collections.emptyList());
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
@ -496,7 +496,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean @@ -496,7 +496,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
return InjectionMetadata.forElements(elements, clazz);
}
@Nullable

23
spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java

@ -80,6 +80,24 @@ import org.springframework.util.ReflectionUtils; @@ -80,6 +80,24 @@ import org.springframework.util.ReflectionUtils;
public class InitDestroyAnnotationBeanPostProcessor
implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
private final transient LifecycleMetadata emptyLifecycleMetadata =
new LifecycleMetadata(Object.class, Collections.emptyList(), Collections.emptyList()) {
@Override
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
}
@Override
public void invokeInitMethods(Object target, String beanName) {
}
@Override
public void invokeDestroyMethods(Object target, String beanName) {
}
@Override
public boolean hasDestroyMethods() {
return false;
}
};
protected transient Log logger = LogFactory.getLog(getClass());
@Nullable
@ -200,7 +218,7 @@ public class InitDestroyAnnotationBeanPostProcessor @@ -200,7 +218,7 @@ public class InitDestroyAnnotationBeanPostProcessor
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return new LifecycleMetadata(clazz, Collections.emptyList(), Collections.emptyList());
return this.emptyLifecycleMetadata;
}
List<LifecycleElement> initMethods = new ArrayList<>();
@ -233,7 +251,8 @@ public class InitDestroyAnnotationBeanPostProcessor @@ -233,7 +251,8 @@ public class InitDestroyAnnotationBeanPostProcessor
}
while (targetClass != null && targetClass != Object.class);
return new LifecycleMetadata(clazz, initMethods, destroyMethods);
return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}

46
spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -22,6 +22,7 @@ import java.lang.reflect.InvocationTargetException; @@ -22,6 +22,7 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
@ -47,6 +48,23 @@ import org.springframework.util.ReflectionUtils; @@ -47,6 +48,23 @@ import org.springframework.util.ReflectionUtils;
*/
public class InjectionMetadata {
/**
* An empty {@code InjectionMetadata} instance with no-op callbacks.
* @since 5.2
*/
public static final InjectionMetadata EMPTY = new InjectionMetadata(Object.class, Collections.emptyList()) {
@Override
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
}
@Override
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) {
}
@Override
public void clear(@Nullable PropertyValues pvs) {
}
};
private static final Log logger = LogFactory.getLog(InjectionMetadata.class);
private final Class<?> targetClass;
@ -57,6 +75,14 @@ public class InjectionMetadata { @@ -57,6 +75,14 @@ public class InjectionMetadata {
private volatile Set<InjectedElement> checkedElements;
/**
* Create a new {@code InjectionMetadata instance}.
* <p>Preferably use {@link #forElements} for reusing the {@link #EMPTY}
* instance in case of no elements.
* @param targetClass the target class
* @param elements the associated elements to inject
* @see #forElements
*/
public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
@ -108,6 +134,24 @@ public class InjectionMetadata { @@ -108,6 +134,24 @@ public class InjectionMetadata {
}
/**
* Return an {@code InjectionMetadata} instance, possibly for empty elements.
* @param elements the elements to inject (possibly empty)
* @param clazz the target class
* @return a new {@code InjectionMetadata} instance,
* or {@link #EMPTY} in case of no elements
* @since 5.2
*/
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
return (elements.isEmpty() ? InjectionMetadata.EMPTY : new InjectionMetadata(clazz, elements));
}
/**
* Check whether the given injection metadata needs to be refreshed.
* @param metadata the existing metadata instance
* @param clazz the current target class
* @return {@code true} indicating a refresh, {@code false} otherwise
*/
public static boolean needsRefresh(@Nullable InjectionMetadata metadata, Class<?> clazz) {
return (metadata == null || metadata.targetClass != clazz);
}

4
spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java

@ -369,7 +369,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean @@ -369,7 +369,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, resourceAnnotationTypes)) {
return new InjectionMetadata(clazz, Collections.emptyList());
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
@ -448,7 +448,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean @@ -448,7 +448,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
return InjectionMetadata.forElements(elements, clazz);
}
/**

5
spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java

@ -24,7 +24,6 @@ import java.lang.reflect.Method; @@ -24,7 +24,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@ -416,7 +415,7 @@ public class PersistenceAnnotationBeanPostProcessor @@ -416,7 +415,7 @@ public class PersistenceAnnotationBeanPostProcessor
private InjectionMetadata buildPersistenceMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(PersistenceContext.class, PersistenceUnit.class))) {
return new InjectionMetadata(clazz, Collections.emptyList());
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
@ -459,7 +458,7 @@ public class PersistenceAnnotationBeanPostProcessor @@ -459,7 +458,7 @@ public class PersistenceAnnotationBeanPostProcessor
}
while (targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
return InjectionMetadata.forElements(elements, clazz);
}
/**

Loading…
Cancel
Save