XML constructor-arg element allows for specifying a constructor argument by name now, with target argument names read from the class file via ASM or from Java 6's @ConstructorProperties annotation (SPR-3313)

This commit is contained in:
Juergen Hoeller
2009-06-03 10:21:57 +00:00
parent 0a0b10b2ff
commit 53333c3ed0
18 changed files with 530 additions and 141 deletions

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");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.beans.factory.xml;
import java.beans.ConstructorProperties;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collection;
@@ -23,7 +24,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import org.springframework.beans.BeansException;
@@ -39,7 +39,6 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.MethodReplacer;
/**
* Types used by {@link XmlBeanFactoryTests} and its attendant XML config files.
*
@@ -55,11 +54,11 @@ final class XmlBeanFactoryTestTypes { }
*/
@SuppressWarnings("serial")
class ConstructorDependenciesBean implements Serializable {
private int age;
private String name;
private TestBean spouse1;
private TestBean spouse2;
@@ -83,6 +82,7 @@ class ConstructorDependenciesBean implements Serializable {
this.spouse2 = spouse2;
}
@ConstructorProperties({"spouse", "otherSpouse", "myAge"})
public ConstructorDependenciesBean(TestBean spouse1, TestBean spouse2, int age) {
this.spouse1 = spouse1;
this.spouse2 = spouse2;
@@ -122,7 +122,33 @@ class ConstructorDependenciesBean implements Serializable {
public void setName(String name) {
this.name = name;
}
}
class SimpleConstructorArgBean {
private int age;
private String name;
public SimpleConstructorArgBean() {
}
public SimpleConstructorArgBean(int age) {
this.age = age;
}
public SimpleConstructorArgBean(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="rod1" class="org.springframework.beans.factory.xml.ConstructorDependenciesBean">
<constructor-arg><ref bean="kerry2"/></constructor-arg>
@@ -104,11 +104,14 @@
</bean>
<bean id="rod16" class="org.springframework.beans.factory.xml.ConstructorDependenciesBean">
<constructor-arg><ref bean="kerry2"/></constructor-arg>
<constructor-arg><ref bean="kerry1"/></constructor-arg>
<constructor-arg name="otherSpouse"><ref bean="kerry1"/></constructor-arg>
<constructor-arg name="spouse"><ref bean="kerry2"/></constructor-arg>
<constructor-arg><value>29</value></constructor-arg>
</bean>
<bean id="rod17" class="org.springframework.beans.factory.xml.SimpleConstructorArgBean" scope="prototype">
</bean>
<bean id="kerry1" class="org.springframework.beans.TestBean">
<property name="name">
<value>Kerry1</value>

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");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,6 @@
package org.springframework.beans.factory.xml;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -29,7 +26,11 @@ import java.net.URL;
import java.util.Map;
import org.apache.commons.logging.LogFactory;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Test;
import org.xml.sax.InputSource;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
@@ -62,7 +63,6 @@ import org.springframework.core.io.support.EncodedResource;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.SerializationTestUtils;
import org.springframework.util.StopWatch;
import org.xml.sax.InputSource;
/**
* Miscellaneous tests for XML bean definitions.
@@ -920,11 +920,11 @@ public final class XmlBeanFactoryTests {
ConstructorDependenciesBean rod9 = (ConstructorDependenciesBean) xbf.getBean("rod9");
assertEquals(99, rod9.getAge());
ConstructorDependenciesBean rod9a = (ConstructorDependenciesBean) xbf.getBean("rod9", new Object[] {new Integer(98)});
ConstructorDependenciesBean rod9a = (ConstructorDependenciesBean) xbf.getBean("rod9", 98);
assertEquals(98, rod9a.getAge());
ConstructorDependenciesBean rod9b = (ConstructorDependenciesBean) xbf.getBean("rod9", new Object[] {"myName"});
ConstructorDependenciesBean rod9b = (ConstructorDependenciesBean) xbf.getBean("rod9", "myName");
assertEquals("myName", rod9b.getName());
ConstructorDependenciesBean rod9c = (ConstructorDependenciesBean) xbf.getBean("rod9", new Object[] {new Integer(97)});
ConstructorDependenciesBean rod9c = (ConstructorDependenciesBean) xbf.getBean("rod9", 97);
assertEquals(97, rod9c.getAge());
ConstructorDependenciesBean rod10 = (ConstructorDependenciesBean) xbf.getBean("rod10");
@@ -955,6 +955,20 @@ public final class XmlBeanFactoryTests {
assertEquals(29, rod16.getAge());
}
public @Test void testPrototypeWithExplicitArguments() {
XmlBeanFactory xbf = new XmlBeanFactory(CONSTRUCTOR_ARG_CONTEXT);
SimpleConstructorArgBean cd1 = (SimpleConstructorArgBean) xbf.getBean("rod17");
assertEquals(0, cd1.getAge());
SimpleConstructorArgBean cd2 = (SimpleConstructorArgBean) xbf.getBean("rod17", 98);
assertEquals(98, cd2.getAge());
SimpleConstructorArgBean cd3 = (SimpleConstructorArgBean) xbf.getBean("rod17", "myName");
assertEquals("myName", cd3.getName());
SimpleConstructorArgBean cd4 = (SimpleConstructorArgBean) xbf.getBean("rod17");
assertEquals(0, cd4.getAge());
SimpleConstructorArgBean cd5 = (SimpleConstructorArgBean) xbf.getBean("rod17", 97);
assertEquals(97, cd5.getAge());
}
public @Test void testConstructorArgWithSingleMatch() {
XmlBeanFactory xbf = new XmlBeanFactory(CONSTRUCTOR_ARG_CONTEXT);
File file = (File) xbf.getBean("file");

View File

@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<beans>
<import resource="ClassPathXmlApplicationContextTests-resourceImport.xml"/>
<import resource="ClassPathXmlApplicationContextTests-resourceIm*.xml"/>
<bean id="resource2" class="org.springframework.beans.ResourceTestBean">
<constructor-arg index="0">
<constructor-arg name="inputStream">
<value>classpath:org/springframework/beans/factory/xml/test.properties</value>
</constructor-arg>
<constructor-arg index="1">
<value>classpath:org/springframework/beans/factory/xml/test.properties</value>
<constructor-arg name="resource">
<value>test.properties</value>
</constructor-arg>
</bean>

View File

@@ -5,7 +5,7 @@
<bean id="resource1" class="org.springframework.beans.ResourceTestBean">
<property name="resource">
<value>classpath:org/springframework/beans/factory/xml/test.properties</value>
<value>test.properties</value>
</property>
<property name="inputStream">
<value>classpath:org/springframework/beans/factory/xml/test.properties</value>

View File

@@ -322,7 +322,7 @@ public final class ClassPathXmlApplicationContextTests {
ClassPathXmlApplicationContext ctx =
new ClassPathXmlApplicationContext(RESOURCE_CONTEXT) {
public Resource getResource(String location) {
if (FQ_TEST_PROPERTIES.equals(location)) {
if (TEST_PROPERTIES.equals(location)) {
return new ClassPathResource(TEST_PROPERTIES, ClassPathXmlApplicationContextTests.class);
}
return super.getResource(location);
@@ -336,13 +336,13 @@ public final class ClassPathXmlApplicationContextTests {
assertEquals("contexttest", writer.toString());
writer = new StringWriter();
FileCopyUtils.copy(new InputStreamReader(resource1.getInputStream()), writer);
assertEquals("contexttest", writer.toString());
assertEquals("test", writer.toString());
writer = new StringWriter();
FileCopyUtils.copy(new InputStreamReader(resource2.getResource().getInputStream()), writer);
assertEquals("contexttest", writer.toString());
writer = new StringWriter();
FileCopyUtils.copy(new InputStreamReader(resource2.getInputStream()), writer);
assertEquals("contexttest", writer.toString());
assertEquals("test", writer.toString());
ctx.close();
}