full compliance with the JSR-330 TCK
This commit is contained in:
parent
a429e230b6
commit
94533976d0
|
|
@ -27,6 +27,7 @@ import java.lang.reflect.Modifier;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -270,28 +271,16 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
return (candidateConstructors.length > 0 ? candidateConstructors : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
|
||||
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectFields(bean, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Autowiring of fields failed", ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValues postProcessPropertyValues(
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
|
||||
|
||||
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectMethods(bean, beanName, pvs);
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Autowiring of methods failed", ex);
|
||||
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
|
||||
}
|
||||
return pvs;
|
||||
}
|
||||
|
|
@ -300,15 +289,16 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
* 'Native' processing method for direct calls with an arbitrary target instance,
|
||||
* resolving all of its fields and methods which are annotated with <code>@Autowired</code>.
|
||||
* @param bean the target instance to process
|
||||
* @throws BeansException if autowiring failed
|
||||
*/
|
||||
public void processInjection(Object bean) throws BeansException {
|
||||
InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
|
||||
Class<?> clazz = bean.getClass();
|
||||
InjectionMetadata metadata = findAutowiringMetadata(clazz);
|
||||
try {
|
||||
metadata.injectFields(bean, null);
|
||||
metadata.injectMethods(bean, null, null);
|
||||
metadata.inject(bean, null, null);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException("Autowiring of fields/methods failed", ex);
|
||||
throw new BeanCreationException("Injection of autowired dependencies failed for class [" + clazz + "]", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -320,36 +310,49 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
|||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(clazz);
|
||||
if (metadata == null) {
|
||||
final InjectionMetadata newMetadata = new InjectionMetadata(clazz);
|
||||
ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
|
||||
public void doWith(Field field) {
|
||||
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
Class<?> targetClass = clazz;
|
||||
|
||||
do {
|
||||
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
for (Field field : targetClass.getDeclaredFields()) {
|
||||
Annotation annotation = findAutowiredAnnotation(field);
|
||||
if (annotation != null) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("Autowired annotation is not supported on static fields");
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static fields: " + field);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
newMetadata.addInjectedField(new AutowiredFieldElement(field, required));
|
||||
currElements.add(new AutowiredFieldElement(field, required));
|
||||
}
|
||||
}
|
||||
});
|
||||
ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
for (Method method : targetClass.getDeclaredMethods()) {
|
||||
Annotation annotation = findAutowiredAnnotation(method);
|
||||
if (annotation != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
throw new IllegalStateException("Autowired annotation is not supported on static methods");
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation is not supported on static methods: " + method);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (method.getParameterTypes().length == 0) {
|
||||
throw new IllegalStateException("Autowired annotation requires at least one argument: " + method);
|
||||
if (logger.isWarnEnabled()) {
|
||||
logger.warn("Autowired annotation should be used on methods with actual parameters: " + method);
|
||||
}
|
||||
}
|
||||
boolean required = determineRequiredStatus(annotation);
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
newMetadata.addInjectedMethod(new AutowiredMethodElement(method, required, pd));
|
||||
currElements.add(new AutowiredMethodElement(method, required, pd));
|
||||
}
|
||||
}
|
||||
});
|
||||
metadata = newMetadata;
|
||||
elements.addAll(0, currElements);
|
||||
targetClass = targetClass.getSuperclass();
|
||||
}
|
||||
while (targetClass != null && targetClass != Object.class);
|
||||
|
||||
metadata = new InjectionMetadata(clazz, elements);
|
||||
this.injectionMetadataCache.put(clazz, metadata);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,42 +49,21 @@ public class InjectionMetadata {
|
|||
|
||||
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
|
||||
private String targetClassName;
|
||||
|
||||
private final Set<InjectedElement> injectedFields = new LinkedHashSet<InjectedElement>();
|
||||
|
||||
private final Set<InjectedElement> injectedMethods = new LinkedHashSet<InjectedElement>();
|
||||
private final Set<InjectedElement> injectedElements;
|
||||
|
||||
|
||||
public InjectionMetadata() {
|
||||
}
|
||||
|
||||
public InjectionMetadata(Class targetClass) {
|
||||
this.targetClassName = targetClass.getName();
|
||||
}
|
||||
|
||||
|
||||
public void addInjectedField(InjectedElement element) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found injected field on class [" + this.targetClassName + "]: " + element);
|
||||
public InjectionMetadata(Class targetClass, Collection<InjectedElement> elements) {
|
||||
this.injectedElements = new LinkedHashSet<InjectedElement>();
|
||||
for (InjectedElement element : elements) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found injected element on class [" + targetClass.getName() + "]: " + element);
|
||||
}
|
||||
this.injectedElements.add(element);
|
||||
}
|
||||
this.injectedFields.add(element);
|
||||
}
|
||||
|
||||
public void addInjectedMethod(InjectedElement element) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found injected method on class [" + this.targetClassName + "]: " + element);
|
||||
}
|
||||
this.injectedMethods.add(element);
|
||||
}
|
||||
|
||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||
doRegisterConfigMembers(beanDefinition, this.injectedFields);
|
||||
doRegisterConfigMembers(beanDefinition, this.injectedMethods);
|
||||
}
|
||||
|
||||
private void doRegisterConfigMembers(RootBeanDefinition beanDefinition, Collection<InjectedElement> members) {
|
||||
for (Iterator<InjectedElement> it = members.iterator(); it.hasNext();) {
|
||||
for (Iterator<InjectedElement> it = this.injectedElements.iterator(); it.hasNext();) {
|
||||
Member member = it.next().getMember();
|
||||
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
||||
beanDefinition.registerExternallyManagedConfigMember(member);
|
||||
|
|
@ -95,22 +74,10 @@ public class InjectionMetadata {
|
|||
}
|
||||
}
|
||||
|
||||
public void injectFields(Object target, String beanName) throws Throwable {
|
||||
if (!this.injectedFields.isEmpty()) {
|
||||
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
|
||||
if (!this.injectedElements.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : this.injectedFields) {
|
||||
if (debug) {
|
||||
logger.debug("Processing injected field of bean '" + beanName + "': " + element);
|
||||
}
|
||||
element.inject(target, beanName, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void injectMethods(Object target, String beanName, PropertyValues pvs) throws Throwable {
|
||||
if (!this.injectedMethods.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : this.injectedMethods) {
|
||||
for (InjectedElement element : this.injectedElements) {
|
||||
if (debug) {
|
||||
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -780,12 +780,18 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
|||
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class beanType, String beanName)
|
||||
throws BeansException {
|
||||
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof MergedBeanDefinitionPostProcessor) {
|
||||
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
|
||||
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
|
||||
try {
|
||||
for (BeanPostProcessor bp : getBeanPostProcessors()) {
|
||||
if (bp instanceof MergedBeanDefinitionPostProcessor) {
|
||||
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
|
||||
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
|
||||
"Post-processing failed of bean type [" + beanType + "] failed", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2009 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.
|
||||
|
|
@ -16,12 +16,10 @@
|
|||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.BeanDefinitionStoreException;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
|
@ -152,8 +150,8 @@ public class BeanDefinitionReaderUtils {
|
|||
// Register aliases for bean name, if any.
|
||||
String[] aliases = definitionHolder.getAliases();
|
||||
if (aliases != null) {
|
||||
for (int i = 0; i < aliases.length; i++) {
|
||||
registry.registerAlias(beanName, aliases[i]);
|
||||
for (String aliase : aliases) {
|
||||
registry.registerAlias(beanName, aliase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanNameGenerator;
|
||||
|
||||
/**
|
||||
* Convenient adapter for programmatic registration of annotated bean classes.
|
||||
*
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class AnnotatedBeanDefinitionReader {
|
||||
|
||||
private final BeanDefinitionRegistry registry;
|
||||
|
||||
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
|
||||
|
||||
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
|
||||
|
||||
private boolean includeAnnotationConfig = true;
|
||||
|
||||
|
||||
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
|
||||
this.registry = registry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the BeanDefinitionRegistry that this scanner operates on.
|
||||
*/
|
||||
public final BeanDefinitionRegistry getRegistry() {
|
||||
return this.registry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BeanNameGenerator to use for detected bean classes.
|
||||
* <p>Default is a {@link AnnotationBeanNameGenerator}.
|
||||
*/
|
||||
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {
|
||||
this.beanNameGenerator = (beanNameGenerator != null ? beanNameGenerator : new AnnotationBeanNameGenerator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ScopeMetadataResolver to use for detected bean classes.
|
||||
* Note that this will override any custom "scopedProxyMode" setting.
|
||||
* <p>The default is an {@link AnnotationScopeMetadataResolver}.
|
||||
* @see #setScopedProxyMode
|
||||
*/
|
||||
public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {
|
||||
this.scopeMetadataResolver = scopeMetadataResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the proxy behavior for non-singleton scoped beans.
|
||||
* Note that this will override any custom "scopeMetadataResolver" setting.
|
||||
* <p>The default is {@link ScopedProxyMode#NO}.
|
||||
* @see #setScopeMetadataResolver
|
||||
*/
|
||||
public void setScopedProxyMode(ScopedProxyMode scopedProxyMode) {
|
||||
this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(scopedProxyMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify whether to register annotation config post-processors.
|
||||
* <p>The default is to register the post-processors. Turn this off
|
||||
* to be able to ignore the annotations or to process them differently.
|
||||
*/
|
||||
public void setIncludeAnnotationConfig(boolean includeAnnotationConfig) {
|
||||
this.includeAnnotationConfig = includeAnnotationConfig;
|
||||
}
|
||||
|
||||
|
||||
public void registerBeans(Class<?>... annotatedClasses) {
|
||||
for (Class<?> annotatedClass : annotatedClasses) {
|
||||
registerBean(annotatedClass);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass) {
|
||||
registerBean(annotatedClass, null, (Class<? extends Annotation>[]) null);
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
|
||||
registerBean(annotatedClass, null, qualifiers);
|
||||
}
|
||||
|
||||
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
|
||||
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
|
||||
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
|
||||
abd.setScope(scopeMetadata.getScopeName());
|
||||
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
|
||||
if (abd.getMetadata().isAnnotated(Primary.class.getName())) {
|
||||
abd.setPrimary(true);
|
||||
}
|
||||
if (abd.getMetadata().isAnnotated(Lazy.class.getName())) {
|
||||
Boolean value = (Boolean) abd.getMetadata().getAnnotationAttributes(Lazy.class.getName()).get("value");
|
||||
abd.setLazyInit(value);
|
||||
}
|
||||
if (abd.getMetadata().isAnnotated(DependsOn.class.getName())) {
|
||||
String[] value = (String[]) abd.getMetadata().getAnnotationAttributes(DependsOn.class.getName()).get("value");
|
||||
abd.setDependsOn(value);
|
||||
}
|
||||
if (qualifiers != null) {
|
||||
for (Class<? extends Annotation> qualifier : qualifiers) {
|
||||
if (Primary.class.equals(qualifier)) {
|
||||
abd.setPrimary(true);
|
||||
}
|
||||
else if (Lazy.class.equals(qualifier)) {
|
||||
abd.setLazyInit(true);
|
||||
}
|
||||
else {
|
||||
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
|
||||
definitionHolder = applyScopedProxyMode(definitionHolder, scopeMetadata);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
|
||||
|
||||
// Register annotation config processors, if necessary.
|
||||
if (this.includeAnnotationConfig) {
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the specified scope to the given bean definition.
|
||||
* @param definition the bean definition to configure
|
||||
* @param metadata the corresponding scope metadata
|
||||
* @return the final bean definition to use (potentially a proxy)
|
||||
*/
|
||||
private BeanDefinitionHolder applyScopedProxyMode(BeanDefinitionHolder definition, ScopeMetadata metadata) {
|
||||
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
|
||||
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
|
||||
return definition;
|
||||
}
|
||||
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
|
||||
return ScopedProxyCreator.createScopedProxy(definition, this.registry, proxyTargetClass);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -315,5 +315,4 @@ public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateCo
|
|||
return ScopedProxyCreator.createScopedProxy(definition, this.registry, proxyTargetClass);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ import java.net.URL;
|
|||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -62,7 +63,6 @@ import org.springframework.core.Ordered;
|
|||
import org.springframework.jndi.support.SimpleJndiBeanFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -283,13 +283,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
}
|
||||
|
||||
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
|
||||
InjectionMetadata metadata = findResourceMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectFields(bean, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Injection of resource fields failed", ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -298,10 +291,10 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
|
||||
InjectionMetadata metadata = findResourceMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectMethods(bean, beanName, pvs);
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Injection of resource methods failed", ex);
|
||||
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
|
||||
}
|
||||
return pvs;
|
||||
}
|
||||
|
|
@ -314,33 +307,34 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(clazz);
|
||||
if (metadata == null) {
|
||||
final InjectionMetadata newMetadata = new InjectionMetadata(clazz);
|
||||
ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
|
||||
public void doWith(Field field) {
|
||||
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
Class<?> targetClass = clazz;
|
||||
|
||||
do {
|
||||
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
for (Field field : targetClass.getDeclaredFields()) {
|
||||
if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
|
||||
}
|
||||
newMetadata.addInjectedField(new WebServiceRefElement(field, null));
|
||||
currElements.add(new WebServiceRefElement(field, null));
|
||||
}
|
||||
else if (ejbRefClass != null && field.isAnnotationPresent(ejbRefClass)) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("@EJB annotation is not supported on static fields");
|
||||
}
|
||||
newMetadata.addInjectedField(new EjbRefElement(field, null));
|
||||
currElements.add(new EjbRefElement(field, null));
|
||||
}
|
||||
else if (field.isAnnotationPresent(Resource.class)) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("@Resource annotation is not supported on static fields");
|
||||
}
|
||||
if (!ignoredResourceTypes.contains(field.getType().getName())) {
|
||||
newMetadata.addInjectedField(new ResourceElement(field, null));
|
||||
currElements.add(new ResourceElement(field, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
for (Method method : targetClass.getDeclaredMethods()) {
|
||||
if (webServiceRefClass != null && method.isAnnotationPresent(webServiceRefClass) &&
|
||||
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
if (Modifier.isStatic(method.getModifiers())) {
|
||||
|
|
@ -350,7 +344,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
throw new IllegalStateException("@WebServiceRef annotation requires a single-arg method: " + method);
|
||||
}
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
newMetadata.addInjectedMethod(new WebServiceRefElement(method, pd));
|
||||
currElements.add(new WebServiceRefElement(method, pd));
|
||||
}
|
||||
else if (ejbRefClass != null && method.isAnnotationPresent(ejbRefClass) &&
|
||||
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
|
|
@ -361,7 +355,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
throw new IllegalStateException("@EJB annotation requires a single-arg method: " + method);
|
||||
}
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
newMetadata.addInjectedMethod(new EjbRefElement(method, pd));
|
||||
currElements.add(new EjbRefElement(method, pd));
|
||||
}
|
||||
else if (method.isAnnotationPresent(Resource.class) &&
|
||||
method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
|
||||
|
|
@ -374,12 +368,16 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
|||
}
|
||||
if (!ignoredResourceTypes.contains(paramTypes[0].getName())) {
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
newMetadata.addInjectedMethod(new ResourceElement(method, pd));
|
||||
currElements.add(new ResourceElement(method, pd));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
metadata = newMetadata;
|
||||
elements.addAll(0, currElements);
|
||||
targetClass = targetClass.getSuperclass();
|
||||
}
|
||||
while (targetClass != null && targetClass != Object.class);
|
||||
|
||||
metadata = new InjectionMetadata(clazz, elements);
|
||||
this.injectionMetadataCache.put(clazz, metadata);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,19 +16,16 @@
|
|||
|
||||
package org.springframework.context.annotation;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultBeanNameGenerator;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.context.support.AbstractRefreshableApplicationContext;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
|
@ -108,8 +105,7 @@ public class ConfigurationClassApplicationContext extends AbstractRefreshableApp
|
|||
* @see Configuration#value()
|
||||
*/
|
||||
@Override
|
||||
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
|
||||
throws IOException, BeansException {
|
||||
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
|
||||
this.delegate.loadBeanDefinitions(beanFactory);
|
||||
}
|
||||
|
||||
|
|
@ -162,34 +158,27 @@ public class ConfigurationClassApplicationContext extends AbstractRefreshableApp
|
|||
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
|
||||
|
||||
for (Class<?> configClass : this.configClasses) {
|
||||
AbstractBeanDefinition def = BeanDefinitionBuilder.rootBeanDefinition(configClass).getBeanDefinition();
|
||||
|
||||
RootBeanDefinition def = new RootBeanDefinition(configClass);
|
||||
String name = AnnotationUtils.findAnnotation(configClass, Configuration.class).value();
|
||||
if (!StringUtils.hasLength(name)) {
|
||||
name = new DefaultBeanNameGenerator().generateBeanName(def, beanFactory);
|
||||
}
|
||||
|
||||
beanFactory.registerBeanDefinition(name, def);
|
||||
}
|
||||
|
||||
new ConfigurationClassPostProcessor().postProcessBeanFactory(beanFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ConfigurationClassApplicationContext#getBean(Class)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getBean(Class<T> requiredType, AbstractApplicationContext context) {
|
||||
public <T> T getBean(Class<T> requiredType, ListableBeanFactory context) {
|
||||
Assert.notNull(requiredType, "requiredType may not be null");
|
||||
Assert.notNull(context, "context may not be null");
|
||||
|
||||
Map<String, ?> beansOfType = context.getBeansOfType(requiredType);
|
||||
|
||||
Map<String, T> beansOfType = context.getBeansOfType(requiredType);
|
||||
switch (beansOfType.size()) {
|
||||
case 0:
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
case 1:
|
||||
return (T) beansOfType.values().iterator().next();
|
||||
return beansOfType.values().iterator().next();
|
||||
default:
|
||||
throw new NoSuchBeanDefinitionException(requiredType,
|
||||
beansOfType.size() + " matching bean definitions found " +
|
||||
|
|
@ -199,4 +188,5 @@ public class ConfigurationClassApplicationContext extends AbstractRefreshableApp
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* Copyright 2002-2009 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.context.annotation.jsr330;
|
||||
|
||||
import junit.framework.Test;
|
||||
import org.atinject.tck.Tck;
|
||||
import org.atinject.tck.auto.Car;
|
||||
import org.atinject.tck.auto.Convertible;
|
||||
import org.atinject.tck.auto.Drivers;
|
||||
import org.atinject.tck.auto.DriversSeat;
|
||||
import org.atinject.tck.auto.FuelTank;
|
||||
import org.atinject.tck.auto.Seat;
|
||||
import org.atinject.tck.auto.Tire;
|
||||
import org.atinject.tck.auto.V8Engine;
|
||||
import org.atinject.tck.auto.accessories.Cupholder;
|
||||
import org.atinject.tck.auto.accessories.SpareTire;
|
||||
|
||||
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.support.AutowireCandidateQualifier;
|
||||
import org.springframework.beans.factory.support.GenericBeanDefinition;
|
||||
import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
|
||||
import org.springframework.context.annotation.AnnotationConfigUtils;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.context.annotation.ScopeMetadata;
|
||||
import org.springframework.context.annotation.ScopeMetadataResolver;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SpringAtInjectTck {
|
||||
|
||||
public static Test suite() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
AnnotatedBeanDefinitionReader bdr = new AnnotatedBeanDefinitionReader(ac);
|
||||
bdr.setScopeMetadataResolver(new ScopeMetadataResolver() {
|
||||
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
|
||||
ScopeMetadata metadata = new ScopeMetadata();
|
||||
if (definition instanceof AnnotatedBeanDefinition) {
|
||||
AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
|
||||
metadata.setScopeName(annDef.getMetadata().hasAnnotation(javax.inject.Singleton.class.getName()) ?
|
||||
BeanDefinition.SCOPE_SINGLETON : BeanDefinition.SCOPE_PROTOTYPE);
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
});
|
||||
|
||||
bdr.registerBean(Convertible.class);
|
||||
bdr.registerBean(DriversSeat.class, Drivers.class);
|
||||
bdr.registerBean(Seat.class, Primary.class);
|
||||
bdr.registerBean(V8Engine.class);
|
||||
bdr.registerBean(SpareTire.class, "spare");
|
||||
bdr.registerBean(Cupholder.class);
|
||||
bdr.registerBean(Tire.class, Primary.class);
|
||||
bdr.registerBean(FuelTank.class);
|
||||
|
||||
ac.refresh();
|
||||
Car car = ac.getBean("convertible", Car.class);
|
||||
|
||||
return Tck.testsFor(car, false, true);
|
||||
}
|
||||
|
||||
public static Test suiteX() {
|
||||
GenericApplicationContext ac = new GenericApplicationContext();
|
||||
|
||||
GenericBeanDefinition carDef = new GenericBeanDefinition();
|
||||
carDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE);
|
||||
carDef.setBeanClass(Convertible.class);
|
||||
ac.registerBeanDefinition("car", carDef);
|
||||
|
||||
GenericBeanDefinition driversSeatDef = new GenericBeanDefinition();
|
||||
driversSeatDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE);
|
||||
driversSeatDef.setBeanClass(DriversSeat.class);
|
||||
driversSeatDef.addQualifier(new AutowireCandidateQualifier(Drivers.class));
|
||||
ac.registerBeanDefinition("driversSeat", driversSeatDef);
|
||||
|
||||
GenericBeanDefinition seatDef = new GenericBeanDefinition();
|
||||
seatDef.setBeanClass(Seat.class);
|
||||
seatDef.setPrimary(true);
|
||||
ac.registerBeanDefinition("seat", seatDef);
|
||||
|
||||
GenericBeanDefinition engineDef = new GenericBeanDefinition();
|
||||
engineDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE);
|
||||
engineDef.setBeanClass(V8Engine.class);
|
||||
ac.registerBeanDefinition("engine", engineDef);
|
||||
|
||||
GenericBeanDefinition spareDef = new GenericBeanDefinition();
|
||||
spareDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE);
|
||||
spareDef.setBeanClass(SpareTire.class);
|
||||
spareDef.addQualifier(new AutowireCandidateQualifier(Drivers.class));
|
||||
ac.registerBeanDefinition("spare", spareDef);
|
||||
|
||||
GenericBeanDefinition cupholderDef = new GenericBeanDefinition();
|
||||
cupholderDef.setBeanClass(Cupholder.class);
|
||||
ac.registerBeanDefinition("cupholder", cupholderDef);
|
||||
|
||||
GenericBeanDefinition tireDef = new GenericBeanDefinition();
|
||||
tireDef.setScope(GenericBeanDefinition.SCOPE_PROTOTYPE);
|
||||
tireDef.setBeanClass(Tire.class);
|
||||
tireDef.setPrimary(true);
|
||||
ac.registerBeanDefinition("tire", tireDef);
|
||||
|
||||
GenericBeanDefinition fuelTankDef = new GenericBeanDefinition();
|
||||
fuelTankDef.setBeanClass(FuelTank.class);
|
||||
ac.registerBeanDefinition("fuelTank", fuelTankDef);
|
||||
|
||||
AnnotationConfigUtils.registerAnnotationConfigProcessors(ac);
|
||||
ac.refresh();
|
||||
Car car = ac.getBean("car", Car.class);
|
||||
return Tck.testsFor(car, false, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -694,13 +694,28 @@ public abstract class ClassUtils {
|
|||
*/
|
||||
public static Method getMostSpecificMethod(Method method, Class<?> targetClass) {
|
||||
Method specificMethod = null;
|
||||
if (method != null && !Modifier.isPrivate(method.getModifiers()) &&
|
||||
if (method != null && isOverridable(method, targetClass) &&
|
||||
targetClass != null && !targetClass.equals(method.getDeclaringClass())) {
|
||||
specificMethod = ReflectionUtils.findMethod(targetClass, method.getName(), method.getParameterTypes());
|
||||
}
|
||||
return (specificMethod != null ? specificMethod : method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the given method is overridable in the given target class.
|
||||
* @param method the method to check
|
||||
* @param targetClass the target class to check against
|
||||
*/
|
||||
private static boolean isOverridable(Method method, Class targetClass) {
|
||||
if (Modifier.isPrivate(method.getModifiers())) {
|
||||
return false;
|
||||
}
|
||||
if (Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers())) {
|
||||
return true;
|
||||
}
|
||||
return getPackageName(method.getDeclaringClass()).equals(getPackageName(targetClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a static method of a class.
|
||||
* @param methodName the static method name
|
||||
|
|
|
|||
|
|
@ -433,12 +433,12 @@ public abstract class ReflectionUtils {
|
|||
* class and superclasses.
|
||||
* <p>The same named method occurring on subclass and superclass will appear
|
||||
* twice, unless excluded by a {@link MethodFilter}.
|
||||
* @param targetClass class to start looking at
|
||||
* @param clazz class to start looking at
|
||||
* @param mc the callback to invoke for each method
|
||||
* @see #doWithMethods(Class, MethodCallback, MethodFilter)
|
||||
*/
|
||||
public static void doWithMethods(Class<?> targetClass, MethodCallback mc) throws IllegalArgumentException {
|
||||
doWithMethods(targetClass, mc, null);
|
||||
public static void doWithMethods(Class<?> clazz, MethodCallback mc) throws IllegalArgumentException {
|
||||
doWithMethods(clazz, mc, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -446,14 +446,15 @@ public abstract class ReflectionUtils {
|
|||
* class and superclasses.
|
||||
* <p>The same named method occurring on subclass and superclass will appear
|
||||
* twice, unless excluded by the specified {@link MethodFilter}.
|
||||
* @param targetClass class to start looking at
|
||||
* @param clazz class to start looking at
|
||||
* @param mc the callback to invoke for each method
|
||||
* @param mf the filter that determines the methods to apply the callback to
|
||||
*/
|
||||
public static void doWithMethods(Class<?> targetClass, MethodCallback mc, MethodFilter mf)
|
||||
public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
// Keep backing up the inheritance hierarchy.
|
||||
Class<?> targetClass = clazz;
|
||||
do {
|
||||
Method[] methods = targetClass.getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
|
|
@ -469,7 +470,8 @@ public abstract class ReflectionUtils {
|
|||
}
|
||||
}
|
||||
targetClass = targetClass.getSuperclass();
|
||||
} while (targetClass != null);
|
||||
}
|
||||
while (targetClass != null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -489,26 +491,26 @@ public abstract class ReflectionUtils {
|
|||
/**
|
||||
* Invoke the given callback on all fields in the target class, going up the
|
||||
* class hierarchy to get all declared fields.
|
||||
* @param targetClass the target class to analyze
|
||||
* @param clazz the target class to analyze
|
||||
* @param fc the callback to invoke for each field
|
||||
*/
|
||||
public static void doWithFields(Class<?> targetClass, FieldCallback fc) throws IllegalArgumentException {
|
||||
doWithFields(targetClass, fc, null);
|
||||
public static void doWithFields(Class<?> clazz, FieldCallback fc) throws IllegalArgumentException {
|
||||
doWithFields(clazz, fc, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the given callback on all fields in the target class, going up the
|
||||
* class hierarchy to get all declared fields.
|
||||
* @param targetClass the target class to analyze
|
||||
* @param clazz the target class to analyze
|
||||
* @param fc the callback to invoke for each field
|
||||
* @param ff the filter that determines the fields to apply the callback to
|
||||
*/
|
||||
public static void doWithFields(Class<?> targetClass, FieldCallback fc, FieldFilter ff)
|
||||
public static void doWithFields(Class<?> clazz, FieldCallback fc, FieldFilter ff)
|
||||
throws IllegalArgumentException {
|
||||
|
||||
// Keep backing up the inheritance hierarchy.
|
||||
Class<?> targetClass = clazz;
|
||||
do {
|
||||
// Copy each field declared on this class unless it's static or file.
|
||||
Field[] fields = targetClass.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
// Skip static and final fields.
|
||||
|
|
@ -519,12 +521,13 @@ public abstract class ReflectionUtils {
|
|||
fc.doWith(field);
|
||||
}
|
||||
catch (IllegalAccessException ex) {
|
||||
throw new IllegalStateException("Shouldn't be illegal to access field '" + field.getName() + "': "
|
||||
+ ex);
|
||||
throw new IllegalStateException(
|
||||
"Shouldn't be illegal to access field '" + field.getName() + "': " + ex);
|
||||
}
|
||||
}
|
||||
targetClass = targetClass.getSuperclass();
|
||||
} while (targetClass != null && targetClass != Object.class);
|
||||
}
|
||||
while (targetClass != null && targetClass != Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ import java.lang.reflect.Field;
|
|||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
|
@ -59,7 +60,6 @@ import org.springframework.orm.jpa.ExtendedEntityManagerCreator;
|
|||
import org.springframework.orm.jpa.SharedEntityManagerCreator;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* BeanPostProcessor that processes {@link javax.persistence.PersistenceUnit}
|
||||
|
|
@ -302,13 +302,6 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport
|
|||
}
|
||||
|
||||
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
|
||||
InjectionMetadata metadata = findPersistenceMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectFields(bean, beanName);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Injection of persistence fields failed", ex);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -317,10 +310,10 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport
|
|||
|
||||
InjectionMetadata metadata = findPersistenceMetadata(bean.getClass());
|
||||
try {
|
||||
metadata.injectMethods(bean, beanName, pvs);
|
||||
metadata.inject(bean, beanName, pvs);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
throw new BeanCreationException(beanName, "Injection of persistence methods failed", ex);
|
||||
throw new BeanCreationException(beanName, "Injection of persistence dependencies failed", ex);
|
||||
}
|
||||
return pvs;
|
||||
}
|
||||
|
|
@ -346,21 +339,22 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport
|
|||
synchronized (this.injectionMetadataCache) {
|
||||
metadata = this.injectionMetadataCache.get(clazz);
|
||||
if (metadata == null) {
|
||||
final InjectionMetadata newMetadata = new InjectionMetadata(clazz);
|
||||
ReflectionUtils.doWithFields(clazz, new ReflectionUtils.FieldCallback() {
|
||||
public void doWith(Field field) {
|
||||
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
Class<?> targetClass = clazz;
|
||||
|
||||
do {
|
||||
LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<InjectionMetadata.InjectedElement>();
|
||||
for (Field field : targetClass.getDeclaredFields()) {
|
||||
PersistenceContext pc = field.getAnnotation(PersistenceContext.class);
|
||||
PersistenceUnit pu = field.getAnnotation(PersistenceUnit.class);
|
||||
if (pc != null || pu != null) {
|
||||
if (Modifier.isStatic(field.getModifiers())) {
|
||||
throw new IllegalStateException("Persistence annotations are not supported on static fields");
|
||||
}
|
||||
newMetadata.addInjectedField(new PersistenceElement(field, null));
|
||||
currElements.add(new PersistenceElement(field, null));
|
||||
}
|
||||
}
|
||||
});
|
||||
ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
for (Method method : targetClass.getDeclaredMethods()) {
|
||||
PersistenceContext pc = method.getAnnotation(PersistenceContext.class);
|
||||
PersistenceUnit pu = method.getAnnotation(PersistenceUnit.class);
|
||||
if (pc != null || pu != null &&
|
||||
|
|
@ -372,11 +366,15 @@ public class PersistenceAnnotationBeanPostProcessor extends JndiLocatorSupport
|
|||
throw new IllegalStateException("Persistence annotation requires a single-arg method: " + method);
|
||||
}
|
||||
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(method);
|
||||
newMetadata.addInjectedMethod(new PersistenceElement(method, pd));
|
||||
currElements.add(new PersistenceElement(method, pd));
|
||||
}
|
||||
}
|
||||
});
|
||||
metadata = newMetadata;
|
||||
elements.addAll(0, currElements);
|
||||
targetClass = targetClass.getSuperclass();
|
||||
}
|
||||
while (targetClass != null && targetClass != Object.class);
|
||||
|
||||
metadata = new InjectionMetadata(clazz, elements);
|
||||
this.injectionMetadataCache.put(clazz, metadata);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue