@Resource names may use ${...} placeholders (SPR-5656)

This commit is contained in:
Juergen Hoeller 2009-04-09 09:14:06 +00:00
parent 3cac9267e9
commit 859497b171
4 changed files with 33 additions and 14 deletions

View File

@ -187,6 +187,13 @@ public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, Single
*/ */
void addEmbeddedValueResolver(StringValueResolver valueResolver); void addEmbeddedValueResolver(StringValueResolver valueResolver);
/**
* Resolve the given embedded value, e.g. an annotation attribute.
* @param value the value to resolve
* @return the resolved value (may be the original value as-is)
*/
String resolveEmbeddedValue(String value);
/** /**
* Add a new BeanPostProcessor that will get applied to beans created * Add a new BeanPostProcessor that will get applied to beans created
* by this factory. To be invoked during factory configuration. * by this factory. To be invoked during factory configuration.

View File

@ -660,12 +660,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
this.embeddedValueResolvers.add(valueResolver); this.embeddedValueResolvers.add(valueResolver);
} }
/** public String resolveEmbeddedValue(String value) {
* Resolve the given embedded value, e.g. an annotation attribute.
* @param value the value to resolve
* @return the resolved value (may be the original value as-is)
*/
protected String resolveEmbeddedValue(String value) {
String result = value; String result = value;
for (StringValueResolver resolver : this.embeddedValueResolvers) { for (StringValueResolver resolver : this.embeddedValueResolvers) {
result = resolver.resolveStringValue(result); result = resolver.resolveStringValue(result);

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -34,7 +34,6 @@ import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -422,8 +421,8 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
protected Object autowireResource(BeanFactory factory, LookupElement element, String requestingBeanName) protected Object autowireResource(BeanFactory factory, LookupElement element, String requestingBeanName)
throws BeansException { throws BeansException {
Object resource = null; Object resource;
Set<String> autowiredBeanNames = null; Set<String> autowiredBeanNames;
String name = element.name; String name = element.name;
if (this.fallbackToDefaultTypeMatch && element.isDefaultName && if (this.fallbackToDefaultTypeMatch && element.isDefaultName &&
@ -521,6 +520,9 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
resourceName = Introspector.decapitalize(resourceName.substring(3)); resourceName = Introspector.decapitalize(resourceName.substring(3));
} }
} }
else if (beanFactory instanceof ConfigurableBeanFactory){
resourceName = ((ConfigurableBeanFactory) beanFactory).resolveEmbeddedValue(resourceName);
}
if (resourceType != null && !Object.class.equals(resourceType)) { if (resourceType != null && !Object.class.equals(resourceType)) {
checkResourceType(resourceType); checkResourceType(resourceType);
} }
@ -588,7 +590,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
@Override @Override
protected Object getResourceToInject(Object target, String requestingBeanName) { protected Object getResourceToInject(Object target, String requestingBeanName) {
Service service = null; Service service;
try { try {
service = (Service) getResource(this, requestingBeanName); service = (Service) getResource(this, requestingBeanName);
} }

View File

@ -16,6 +16,8 @@
package org.springframework.context.annotation; package org.springframework.context.annotation;
import java.util.Properties;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
@ -31,6 +33,7 @@ import org.springframework.beans.TestBean;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor; import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
@ -171,10 +174,16 @@ public class CommonAnnotationBeanPostProcessorTests {
public void testExtendedResourceInjection() { public void testExtendedResourceInjection() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor(); CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
bpp.setResourceFactory(bf); bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp); bf.addBeanPostProcessor(bpp);
bf.registerResolvableDependency(BeanFactory.class, bf); bf.registerResolvableDependency(BeanFactory.class, bf);
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties props = new Properties();
props.setProperty("tb", "testBean3");
ppc.setProperties(props);
ppc.postProcessBeanFactory(bf);
bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ExtendedResourceInjectionBean.class)); bf.registerBeanDefinition("annotatedBean", new RootBeanDefinition(ExtendedResourceInjectionBean.class));
bf.registerBeanDefinition("annotatedBean2", new RootBeanDefinition(NamedResourceInjectionBean.class)); bf.registerBeanDefinition("annotatedBean2", new RootBeanDefinition(NamedResourceInjectionBean.class));
TestBean tb = new TestBean(); TestBean tb = new TestBean();
@ -212,10 +221,16 @@ public class CommonAnnotationBeanPostProcessorTests {
public void testExtendedResourceInjectionWithOverriding() { public void testExtendedResourceInjectionWithOverriding() {
DefaultListableBeanFactory bf = new DefaultListableBeanFactory(); DefaultListableBeanFactory bf = new DefaultListableBeanFactory();
CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor(); CommonAnnotationBeanPostProcessor bpp = new CommonAnnotationBeanPostProcessor();
bpp.setResourceFactory(bf); bpp.setBeanFactory(bf);
bf.addBeanPostProcessor(bpp); bf.addBeanPostProcessor(bpp);
bf.registerResolvableDependency(BeanFactory.class, bf); bf.registerResolvableDependency(BeanFactory.class, bf);
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
Properties props = new Properties();
props.setProperty("tb", "testBean3");
ppc.setProperties(props);
ppc.postProcessBeanFactory(bf);
RootBeanDefinition annotatedBd = new RootBeanDefinition(ExtendedResourceInjectionBean.class); RootBeanDefinition annotatedBd = new RootBeanDefinition(ExtendedResourceInjectionBean.class);
TestBean tb5 = new TestBean(); TestBean tb5 = new TestBean();
annotatedBd.getPropertyValues().addPropertyValue("testBean2", tb5); annotatedBd.getPropertyValues().addPropertyValue("testBean2", tb5);
@ -387,7 +402,7 @@ public class CommonAnnotationBeanPostProcessorTests {
super.setTestBean2(testBean2); super.setTestBean2(testBean2);
} }
@Resource(name="testBean3", type=ITestBean.class) @Resource(name="${tb}", type=ITestBean.class)
private void setTestBean4(ITestBean testBean4) { private void setTestBean4(ITestBean testBean4) {
this.testBean4 = testBean4; this.testBean4 = testBean4;
} }