论坛首页 Java企业应用论坛

spring 的Type2 方式IOC中的setter方法能否重载?

浏览 5380 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2004-11-15  
配置:
spring 1.1.1
eclipse 3
jdk 1.4.2
win 2k

配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
	<bean id="personManager" class="org.genomics.xubin.PersonManager" autowire="autodetect">
		<property name="person">
<!--			<value>xubin</value>-->
			<ref bean="person"></ref>
		</property>
		<property name="anotherPerson">
			<ref bean="anotherPerson"/>
<!--			<value>hehehe</value>-->
		</property>
	</bean>
	<bean id="person" class="org.genomics.xubin.Person">
		<property name="name">
			<value>xubin</value>
		</property>
	</bean>
	<bean id="anotherPerson" class="org.genomics.xubin.Person">
		<property name="name">
			<value>hehehe</value>
		</property>
	</bean>
</beans>


代码:
public class Person {
	private String name;

	/**
	 * @param name
	 */
	public Person(String name); {
		this.name = name;
	}
	/**
	 * @param name The name to set.
	 */
	public void setName(String name); {
		this.name = name;
	}
	
	/* (non-Javadoc);
	 * @see java.lang.Object#toString();
	 */
	public String toString(); {
		// TODO Auto-generated method stub
		return this.name;
	}
	
	public Person();{
		
	}
}

public class PersonManager {
	private Person person;

	private Person anotherPerson;
	
	public void setPerson(String name); {
		this.person = new Person(name);;
	}

	/**
	 * @param anotherPerson
	 *            The anotherPerson to set.
	 */
	public void setAnotherPerson(Person anotherPerson); {
		this.anotherPerson = anotherPerson;
	}

	/**
	 * @param person
	 *            The person to set.
	 */
	public void setPerson(Person person); {
		this.person = person;
	}

	public void setAnotherPerson(String name); {
		this.anotherPerson = new Person(name);;
	}

	/*
	 * (non-Javadoc);
	 * 
	 * @see java.lang.Object#toString();
	 */
	public String toString(); {
		// TODO Auto-generated method stub
		return "the first person is " + this.person.toString();
				+ "and another person is" + this.anotherPerson.toString();;
	}
}
   发表时间:2004-11-15  
我的分析:
不好意思,出错信息有点多。其实是一个很简单的例子。personManager里的setPerson和setAnotherPerson都是有重载的,可以接受一个Person对象或者接受一个String,然后自己new一个Person出来。
如果我不用&lt;ref bean&gt;来引用person而改用直接用&lt;value&gt;xubin&lt;/value&gt;,就可以。
让我不解的是,anotherPerson 就可以用&lt;ref-bean&gt;。这两个字段在personManager里面的地位是一样的啊,奇怪
而且出错信息里(下面加粗的那段)可以看到,spring得到的这两个的字段类型都不一样。如果我需要setter能重载,应该怎么做?谢谢了

出错信息:
starting
2004-11-15 13:15:19,531 INFO [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Loading XML bean definitions from file [F:\eclipse\workspace\Test\ApplicationContext.xml]
2004-11-15 13:15:19,546 DEBUG [org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - Using JAXP implementation [org.apache.crimson.jaxp.DocumentBuilderFactoryImpl@1bd0dd4]
2004-11-15 13:15:19,609 DEBUG [org.springframework.context.support.ResourceEntityResolver] - Trying to resolve XML entity with public ID [-//SPRING//DTD BEAN//EN] and system ID [http://www.springframework.org/dtd/spring-beans.dtd]
2004-11-15 13:15:19,609 DEBUG [org.springframework.context.support.ResourceEntityResolver] - Trying to locate [spring-beans.dtd] under [/org/springframework/beans/factory/xml/]
2004-11-15 13:15:19,609 DEBUG [org.springframework.context.support.ResourceEntityResolver] - Found beans DTD [http://www.springframework.org/dtd/spring-beans.dtd] in classpath
2004-11-15 13:15:19,703 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Loading bean definitions
2004-11-15 13:15:19,703 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Default lazy init 'false'
2004-11-15 13:15:19,703 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Default dependency check 'none'
2004-11-15 13:15:19,718 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Default autowire 'no'
2004-11-15 13:15:19,765 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Registering bean definition with id 'personManager'
2004-11-15 13:15:19,765 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Registering bean definition with id 'person'
2004-11-15 13:15:19,765 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Registering bean definition with id 'anotherPerson'
2004-11-15 13:15:19,781 DEBUG [org.springframework.beans.factory.xml.DefaultXmlBeanDefinitionParser] - Found 3 <bean> elements defining beans
2004-11-15 13:15:19,781 INFO [org.springframework.context.support.FileSystemXmlApplicationContext] - Bean factory for application context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=32389396]: org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [personManager,person,anotherPerson]; Root of BeanFactory hierarchy
2004-11-15 13:15:19,828 INFO [org.springframework.context.support.FileSystemXmlApplicationContext] - 3 beans defined in ApplicationContext [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=32389396]
2004-11-15 13:15:19,828 INFO [org.springframework.context.support.FileSystemXmlApplicationContext] - No MessageSource found for context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=32389396]: using empty default
2004-11-15 13:15:19,843 INFO [org.springframework.context.support.FileSystemXmlApplicationContext] - No ApplicationEventMulticaster found for context [org.springframework.context.support.FileSystemXmlApplicationContext;hashCode=32389396]: using default
2004-11-15 13:15:19,843 INFO [org.springframework.context.support.FileSystemXmlApplicationContext] - Refreshing listeners
2004-11-15 13:15:19,843 DEBUG [org.springframework.context.support.FileSystemXmlApplicationContext] - Found 0 listeners in bean factory
2004-11-15 13:15:19,843 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Pre-instantiating singletons in factory [org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [personManager,person,anotherPerson]; Root of BeanFactory hierarchy]
2004-11-15 13:15:19,843 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating shared instance of singleton bean 'personManager'
2004-11-15 13:15:19,859 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'personManager' with merged definition [Root bean with class [org.genomics.xubin.PersonManager] defined in file [F:\eclipse\workspace\Test\ApplicationContext.xml]]
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Getting BeanInfo for class [org.genomics.xubin.PersonManager]
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Caching PropertyDescriptors for class [org.genomics.xubin.PersonManager]
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Found property 'anotherPerson' of type [class org.genomics.xubin.Person]; editor=[null]
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Found property 'class' of type [class java.lang.Class]; editor=[null]
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Found property 'person' of type [class java.lang.String]; editor=[null]
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Class [org.genomics.xubin.PersonManager] is cache-safe
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Resolving reference from property 'person' in bean 'personManager' to bean 'person'
2004-11-15 13:15:19,953 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating shared instance of singleton bean 'person'
2004-11-15 13:15:19,953 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'person' with merged definition [Root bean with class [org.genomics.xubin.Person] defined in file [F:\eclipse\workspace\Test\ApplicationContext.xml]]
2004-11-15 13:15:19,968 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Getting BeanInfo for class [org.genomics.xubin.Person]
2004-11-15 13:15:19,968 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Caching PropertyDescriptors for class [org.genomics.xubin.Person]
2004-11-15 13:15:19,968 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Found property 'class' of type [class java.lang.Class]; editor=[null]
2004-11-15 13:15:19,968 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Found property 'name' of type [class java.lang.String]; editor=[null]
2004-11-15 13:15:19,968 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Class [org.genomics.xubin.Person] is cache-safe
2004-11-15 13:15:19,984 DEBUG [org.springframework.beans.BeanWrapperImpl] - About to invoke write method [public void org.genomics.xubin.Person.setName(java.lang.String)] on object of class [org.genomics.xubin.Person]
2004-11-15 13:15:19,984 DEBUG [org.springframework.beans.BeanWrapperImpl] - Invoked write method [public void org.genomics.xubin.Person.setName(java.lang.String)] with value [xubin]
2004-11-15 13:15:19,984 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Invoking BeanPostProcessors before initialization of bean 'person'
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Invoking BeanPostProcessors after initialization of bean 'person'
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Resolving reference from property 'anotherPerson' in bean 'personManager' to bean 'anotherPerson'
2004-11-15 13:15:19,999 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating shared instance of singleton bean 'anotherPerson'
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'anotherPerson' with merged definition [Root bean with class [org.genomics.xubin.Person] defined in file [F:\eclipse\workspace\Test\ApplicationContext.xml]]
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.CachedIntrospectionResults] - Using cached introspection results for class [org.genomics.xubin.Person]
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.BeanWrapperImpl] - About to invoke write method [public void org.genomics.xubin.Person.setName(java.lang.String)] on object of class [org.genomics.xubin.Person]
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.BeanWrapperImpl] - Invoked write method [public void org.genomics.xubin.Person.setName(java.lang.String)] with value [hehehe]
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Invoking BeanPostProcessors before initialization of bean 'anotherPerson'
2004-11-15 13:15:19,999 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Invoking BeanPostProcessors after initialization of bean 'anotherPerson'
2004-11-15 13:15:20,015 DEBUG [org.springframework.beans.BeanWrapperImpl] - About to invoke write method [public void org.genomics.xubin.PersonManager.setAnotherPerson(org.genomics.xubin.Person)] on object of class [org.genomics.xubin.PersonManager]
2004-11-15 13:15:20,015 DEBUG [org.springframework.beans.BeanWrapperImpl] - Invoked write method [public void org.genomics.xubin.PersonManager.setAnotherPerson(org.genomics.xubin.Person)] with value of type [org.genomics.xubin.Person]
2004-11-15 13:15:20,015 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Destroying singletons in factory {org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [personManager,person,anotherPerson]; Root of BeanFactory hierarchy}
2004-11-15 13:15:20,015 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Retrieving dependent beans for bean 'anotherPerson'
2004-11-15 13:15:20,015 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Applying DestructionAwareBeanPostProcessors to bean with name 'anotherPerson'
2004-11-15 13:15:20,015 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Retrieving dependent beans for bean 'person'
2004-11-15 13:15:20,015 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Applying DestructionAwareBeanPostProcessors to bean with name 'person'
2004-11-15 13:15:20,015 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Destroying inner beans in factory {org.springframework.beans.factory.support.DefaultListableBeanFactory defining beans [personManager,person,anotherPerson]; Root of BeanFactory hierarchy}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personManager' defined in file [F:\eclipse\workspace\Test\ApplicationContext.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyAccessExceptionsException: PropertyAccessExceptionsException (1 errors); nested propertyAccessExceptions are: [org.springframework.beans.TypeMismatchException: Failed to convert property value of type [org.genomics.xubin.Person] to required type [java.lang.String] for property 'person']
PropertyAccessExceptionsException (1 errors)
org.springframework.beans.TypeMismatchException: Failed to convert property value of type [org.genomics.xubin.Person] to required type [java.lang.String] for property 'person'
at org.springframework.beans.BeanWrapperImpl.doTypeConversionIfNecessary(BeanWrapperImpl.java:905)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:673)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:588)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:720)
at org.springframework.beans.BeanWrapperImpl.setPropertyValues(BeanWrapperImpl.java:747)
at org.springframework.beans.BeanWrapperImpl.setPropertyValues(BeanWrapperImpl.java:736)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:840)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:662)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:270)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:205)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:136)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:236)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:284)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:83)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:68)
at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:59)
at org.genomics.xubin.Main.main(Main.java:22)
Exception in thread "main"
0 请登录后投票
   发表时间:2004-11-20  
应该是不能:)
因为spring用了java.beans.Introspector来获取bean的属性.而java.beans.Introspector会把重载的属性合并成一个大杂烩.合并后属性的类型是什么看来好像没有规律 .至于anotherPerson的类型正确,看来只是巧合

解决方法么,也有,只是要绕个圈子了

先说原理:
java.beans.Introspector是用来获取bean的属性,方法,事件等信息的.事实上,这些信息存放在一个实现BeanInfo接口的class中.而且java.beans.Introspector会首先使用程序提供的定制信息,如果找不到定制信息,那么就用reflection去探测.

如果要提供定制的BeanInfo,那么就要设计一个class,这个class的名字要要XXXBeanInfo,就是在你的bean的类型名称后面加上BeanInfo.这个class所在的包没有特别规定,只要在classpath下面,java.beans.Introspector会自动搜索所有的包,不过推荐和你的bean在一起,因为这个包是第一个搜索的地方.

有一个SimpleBeanInfo的类,可以作为我们设计定制BeanInfo的基础.代码如下

   
public class PersonManagerBeanInfo extends SimpleBeanInfo {

    
    /**
     * @see java.beans.BeanInfo#getPropertyDescriptors();
     */
    public PropertyDescriptor[] getPropertyDescriptors(); {
        PropertyDescriptor[]pds=new PropertyDescriptor[2];
        try {
            PropertyDescriptor pd=new PropertyDescriptor("person", PersonManager.class,null,"setPerson");{
                public Class getPropertyType(); {
                    return Person.class;
                }
            };
            pds[0]=pd;
            pd=new PropertyDescriptor("anotherPerson",PersonManager.class,null,"setAnotherPerson");{
                public Class getPropertyType(); {
                    return Person.class;
                }
            };
            pds[1]=pd;
        } catch (IntrospectionException e); {
            //log.error(e);;
            e.printStackTrace();;
        }
        return pds;
        
    }
    

随手写的,有错自己改哈!!!
0 请登录后投票
   发表时间:2004-11-20  
谢谢pikachu的回复。我再在写上面这里例子的时候就已经感觉到这个和内省或者反射有关系,我调换一下重载方法的顺序,结果就不一样。
我这个问题其实是这样来的,spring自带了一个对javamail的封装,里面有一个mimeMessageHelper,可以设定to和from(收件人和发件人)。但是这两个属性的setter是重载过的,可以是传入string也可以是InternetAddress及其数组,所以就有问题了,而且在不同的jdk之间结果也不一样。我是这样解决的,其实也不难,我在调用mimeMessageHelper的那个类里面添加了两个to和from属性,然后在程序里面调用mimeMessageHelper的set方法就可以了。

ps:到什么时候我才也可以随手就写一个示例代码啊:(
0 请登录后投票
   发表时间:2004-11-20  
de3light 写道
谢谢pikachu的回复。我再在写上面这里例子的时候就已经感觉到这个和内省或者反射有关系,我调换一下重载方法的顺序,结果就不一样。
我这个问题其实是这样来的,spring自带了一个对javamail的封装,里面有一个mimeMessageHelper,可以设定to和from(收件人和发件人)。但是这两个属性的setter是重载过的,可以是传入string也可以是InternetAddress及其数组,所以就有问题了,而且在不同的jdk之间结果也不一样。我是这样解决的,其实也不难,我在调用mimeMessageHelper的那个类里面添加了两个to和from属性,然后在程序里面调用mimeMessageHelper的set方法就可以了。

ps:到什么时候我才也可以随手就写一个示例代码啊:(


除了定制BeanInfo外,还有一个简单的解决办法。首先按照标准的JavaBean规范,属性应该有setter/getter。由于getter是不带参数的,那么get是不能重载的,只可能有一个,那么get返回的类型就是这个属性的最的类型。而Introspector首先会用get的类型作为属性类型。所以你只要设计一个该属性的get函数就可以了。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics