《Spring攻略》 第2章 高级Spring IoC容器

1调用静态工厂方法创建Bean

问题:
你打算调用一个静态工厂方法在Spring IoC容器中创建一个Bean,静态工厂方法的目的是在静态方法中封装对象创建过程。

解决方案:
Spring支持调用一个静态工厂方法创建Bean,这个方法应该在factory-method属性中指定。

工作原理:
factory-method

public class ProductCreator {
	public static Product createProduct(int productId){
		if(1 == productId){
			return new Product("xiaomei", 16);
		}else if(2 == productId){
			return new Product("xiaolang", 15);
		}
		throw new IllegalArgumentException("Unknown product");
	}
}

<bean id="productCreator1" class="com.partner4java.spring.factorymethod.ProductCreator"
	factory-method="createProduct">
	<constructor-arg value="1" />
</bean>

<bean id="productCreator2" class="com.partner4java.spring.factorymethod.ProductCreator"
	factory-method="createProduct">
	<constructor-arg value="2" />
</bean>

@Test
public void testFactoryMethod(){
	System.out.println(applicationContext.getBean("productCreator1"));
	System.out.println(applicationContext.getBean("productCreator2"));
}


2调用一个实例工厂方法创建Bean

问题:
你打算调用一个实例工厂方法在Spring IoC容器中创建一个Bean,目的是在另一个对象实例的一个方法中封装对象创建过程。
请求对象的客户可以简单地调用这个方法,不需要了解创建的细节。

解决方案:
Spring支持调用实例工厂方法创建Bean。Bean实例在factory-bean属性中指定,而工厂方法应该在factory-method属性中指定。

工作原理:
factory-bean

package com.partner4java.spring.factorybean;

import java.util.Map;

import com.partner4java.spring.factorymethod.Product;

public class ProductCreator {
	private Map<String, Product> products;

	public void setProducts(Map<String, Product> products) {
		this.products = products;
	}
	
	public Product createProduct(String productId){
		Product product = products.get(productId);
		if(product != null){
			return product;
		}
		throw new IllegalArgumentException("Unknown product");
	}
}

<bean id="productCreator" class="com.partner4java.spring.factorybean.ProductCreator">
	<property name="products">
		<map>
			<entry key="gaofumei">
				<bean class="com.partner4java.spring.factorymethod.Product">
					<constructor-arg value="gaofumei" name="name"/>
					<constructor-arg value="100" name="price"/>
				</bean>
			</entry>
			<entry key="xiaoneinv">
				<bean class="com.partner4java.spring.factorymethod.Product">
					<constructor-arg value="xiaoneinv" name="name"/>
					<constructor-arg value="200" name="price"/>
				</bean>
			</entry>
		</map>
	</property>
</bean>

<bean id="gaofumei" factory-bean="productCreator" factory-method="createProduct">
	<constructor-arg value="gaofumei"/>
</bean>

<bean id="xiaoneinv" factory-bean="productCreator" factory-method="createProduct">
	<constructor-arg value="xiaoneinv"/>
</bean>

@Test
public void testFactoryMethod(){
	System.out.println(applicationContext.getBean("gaofumei"));
	System.out.println(applicationContext.getBean("xiaoneinv"));
}


3从静态字段中声明bean

问题:
你打算从一个静态字段中声明Spring IoC容器中的一个Bean。在Java中,常量值往往声明为静态字段。

解决方案:
为了从静态字段中声明Bean,你可以使用内建的工厂Bean FieldRetrievingFactoryBean,或者Spring 2.X中的<util:contant>标记。

工作原理:
public class ProductConstant {
	public static Product gaofumei = new Product("gaofumei", 100);
	public static Product xiaoneinv = new Product("xiaoneinv", 200);
}

<util:constant id="gaofumei"
	static-field="com.partner4java.spring.constant.ProductConstant.gaofumei" />

<util:constant id="xiaoneinv"
	static-field="com.partner4java.spring.constant.ProductConstant.xiaoneinv" />

@Test
public void testFactoryMethod(){
	System.out.println(applicationContext.getBean("gaofumei"));
	System.out.println(applicationContext.getBean("xiaoneinv"));
}


4从对象属性中声明bean

问题:
你打算从一个对象属性或者嵌套的属性(也就是属性路径)中声明Spring IoC容器中的一个Bean。

解决方案:
为了从一种对象属性或者属性路径中声明Bean,可以使用内建的工厂Bean PropertyPathFactoryBean或者Spring 2.X中的<util:property-path>标记。

工作原理:
public class ProductProperty {
	private Product gaofumei;
	private Product xiaonennv;
	
	public Product getGaofumei() {
		return gaofumei;
	}
	public void setGaofumei(Product gaofumei) {
		this.gaofumei = gaofumei;
	}
	public Product getXiaonennv() {
		return xiaonennv;
	}
	public void setXiaonennv(Product xiaonennv) {
		this.xiaonennv = xiaonennv;
	}
	
}

<bean id="productProperty" class="com.partner4java.spring.property.ProductProperty">
	<property name="gaofumei">
		<bean class="com.partner4java.spring.factorymethod.Product">
			<constructor-arg name="name" value="gaofumei"/>
			<constructor-arg name="price" value="100.1"/>
		</bean>
	</property>
	<property name="xiaonennv">
		<bean class="com.partner4java.spring.factorymethod.Product">
			<constructor-arg name="name" value="xiaonennv"/>
			<constructor-arg name="price" value="200.2"/>
		</bean>
	</property>
</bean>

<util:property-path id="gaofumei" path="productProperty.gaofumei"/>
<util:property-path id="xiaonennv" path="productProperty.xiaonennv"/>


5使用Spring表达式语言

问题:
你希望动态的评估一些条件或者属性,并且将其作为IoC容器中的配置值使用。
你也可能因为自定义范围的情况,必须将某些估值从设计时延迟到运行时。
或者你只是需要一种行为自己的应用添加强大的表达式语言。


解决方案:
使用Spring 3.0的Spring表达式语言(SpEL),这种语言提供了与JSF和JSP中的Unified EL或者对象图形导航语言(OGNL)相似的功能。
SpEL提供了易用的基础架构,可以在Spring容器之外使用。


工作原理:



6设置Bean作用域

问题:
当你在配置文件中声明Bean时,实际上定义了Bean创建的一个模板,而不是实际的Bean实例。
当getBean()方法或者其他的Bean的一个引用请求Bean时,Spring将根据Bean作用域(Scope)确定应该返回的Bean实例。
有时候,你必须为Bean设置正确的作用域而不是默认的作用域。( By default, a bean will be a singleton)


解决方案:
作用域 描述
singleton
在每个Spring IoC容器中一个bean定义对应一个对象实例。

prototype
一个bean定义对应多个对象实例。

request
在一次HTTP请求中,一个bean定义对应一个实例;即每次HTTP请求将会有各自的bean实例, 它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。

session
在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。

global session
在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。


7自定义Bean初始化和析构

问题 :
许多现实世界中的组件在使用之前必须进行某种初始化任务。
在组件的声明周期结束时,也必须要执行相应的任务。

解决方案:
除了注册Bean之外,Spring IoC容器还负责管理Bean的声明周期,允许你在他们的生命期特定时点执行自定义任务。
你的任务应该封装在回调方法中,由Spring IoC容器在核实的时候调用。

Spring IoC容器管理Bean周期的步骤:
1、构造程序或者工厂方法创建Bean实例。
2、向Bean属性设置值和Bean引用。
3、调用初始化回调方法。
4、Bean就绪。
5、容器关闭时,调用析构回调方法。

工作原理:
方法一:实现约定接口
public class Work implements InitializingBean,DisposableBean {

	@Override
	public void destroy() throws Exception {
		System.out.println("离职");
	}
	
	public void vork(){
		System.out.println("working");
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		System.out.println("入职");
	}

}
<bean id="work" class="com.partner4java.spring.initdes.Work"
		scope="prototype" />

方法二:配置文件声明		
public class Work1 {

	public void destroy() throws Exception {
		System.out.println("离职");
	}
	
	public void vork(){
		System.out.println("working");
	}

	public void afterPropertiesSet() throws Exception {
		System.out.println("入职");
	}

}
<bean id="work1" class="com.partner4java.spring.initdes.Work1"
		init-method="afterPropertiesSet" destroy-method="destroy" scope="prototype" />
	
方法三:注解声明
public class Work2 {

	@PreDestroy
	public void destroy() throws Exception {
		System.out.println("离职");
	}
	
	public void vork(){
		System.out.println("working");
	}

	@PostConstruct
	public void afterPropertiesSet() throws Exception {
		System.out.println("入职");
	}

}

<context:annotation-config/>	
<bean id="work2" class="com.partner4java.spring.initdes.Work2"
	scope="prototype" />		


8用Java Config简化XML配置

问题:
你欣赏DI容器的能力,但是希望覆盖一些配置,或者只是希望将更多的配置从XML格式中转移到Java中,可以更好的从重构和类型安全性中获益。


解决方案:
你可以使用Java Config。


工作原理:
Java Config支持强大的,代表了与其他通过XML或者注解的配置选项完全不同的工作方式。
重要的是,Java Config可以与现有方式混合使用。
启用Java配置的最简单方法是使用简单的XML配置文件。


@Configuration标记类:Spring将在类中寻找@Bean定义,指定这个标记@Bean的方法为一个Bean。(也就是指定某个方法返回为一个Bean)


@Lazy:将Bean的构造推迟到必须满足依赖或者应用上下文中显示的访问时。
@DependsOn:指定一个Bean的创建必须在其他Bean创建之后。
@Primary:指定相同接口的多个Bean。


@Import、@Value...


9使Bean感知容器

问题:
一个精心设计的组件应该没有对容器的直接依赖。
但是,有时候Bean有必要了解容器的资源。

解决方案:
Spring将通过一些接口定义的设置方法将对应资源注入到你的Bean中。
Spring中的常见感知接口
感知接口				目标资源
BeanNameAware		IoC容器中配置的实例的Bean名称
BeanFactoryAware	当前的Bean工厂,通过它你可以调用容器的服务。
ApplicationContextAware*	当前应用上下文,通过他你可以调用容器的服务。
MessageSourceAware	消息资源,通过他可以解析文本消息。
ApplicationEventPublisherAware	应用事件发布者,通过他你可以发布应用事件。
ResourceLoaderAware	资源装载器,通过他可以加载外部资源。

你可以实现这些接口,然后试试看你都能获得什么。

工作原理:
public class HelloBeanNameAware implements BeanNameAware {
	private String name;
	
	@Override
	public void setBeanName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "HelloBeanNameAware [name=" + name + "]";
	}
}

public class HelloBeanFactoryAware implements BeanFactoryAware {
	private BeanFactory beanFactory;
	
	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		this.beanFactory = beanFactory;
	}

	@Override
	public String toString() {
		return "HelloBeanFactoryAware [beanFactory=" + beanFactory.getClass().getSimpleName() + "]";
	}

}

public class HelloApplicationContextAware implements ApplicationContextAware {
	private ApplicationContext applicationContext;
	
	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}

	@Override
	public String toString() {
		return "HelloApplicationContextAware [applicationContext="
				+ applicationContext.getClass().getSimpleName() + "]";
	}
	
}


<bean id="helloBeanNameAware" class="com.partner4java.spring.aware.HelloBeanNameAware" />

<bean id="helloBeanFactoryAware" class="com.partner4java.spring.aware.HelloBeanFactoryAware" />

<bean id="helloApplicationContextAware" class="com.partner4java.spring.aware.HelloApplicationContextAware" />

@Test
public void testAware() throws InterruptedException{
	System.out.println(applicationContext.getBean("helloBeanNameAware"));
	System.out.println(applicationContext.getBean("helloBeanFactoryAware"));
	System.out.println(applicationContext.getBean("helloApplicationContextAware"));
	// 后台打印:
	// HelloBeanNameAware [name=helloBeanNameAware]
	// HelloBeanFactoryAware [beanFactory=DefaultListableBeanFactory]
	// HelloApplicationContextAware
	// [applicationContext=ClassPathXmlApplicationContext]
}	


10加载外部资源

问题:
有时候,你的应用可能需要从不同位置(例如文件系统、classpath或者URL)读取外部资源(例如文本文件、XML文件、属性文件或者图像文件)。
通常,你必须处理用于从不同位置加载资源的不同API。

解决方案:
Spring的资源装载器提供统一的getResoure()方法,按照资源路径读取外部资源。你可以为路径指定不同的前缀从不同位置加载资源。
为了从文件系统加载资源,使用file前缀。
从classpath加载资源则使用classpath前缀。
你还可以在资源路径中指定一个URL。

Resource是Spring中代表外部资源的通用接口。Spring提供Resource接口的多个实现。
资源装载器的getResource()方法根据资源路径决定实例化哪一个Resource实现。

工作原理:
方式一:实现接口ResourceLoaderAware(感知接口)
public class HelloResourceLoader implements ResourceLoaderAware {
	private ResourceLoader resourceLoader;
	@Override
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

	public void showResource() throws IOException {
		Resource resource = resourceLoader.getResource("file:D:/cc.txt");
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
		String s = null;
		while((s = bufferedReader.readLine()) != null){
			System.out.println(s);
		}
	}
}

<bean id="helloResourceLoader" class="com.partner4java.spring.resource.HelloResourceLoader"
	init-method="showResource" />

获取bean,会注入感知接口的资源,并执行初始化方法。

方式二:
简单的指定这个Resource属性的资源路径,Spring将使用预先注册属性编辑器ResourceEditor将这个属性转换为一个Resource对象,然后注入你的Bean中。
public class HelloSimpleResourceLoader {
	private Resource resource;

	public void setResource(Resource resource) {
		this.resource = resource;
	}
	
	public void showResource() throws IOException {
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(resource.getInputStream()));
		String s = null;
		while((s = bufferedReader.readLine()) != null){
			System.out.println(s);
		}
	}
}

<bean id="helloSimpleResourceLoader"
	class="com.partner4java.spring.resource.HelloSimpleResourceLoader"
	init-method="showResource">
	<property name="resource">
		<value>classpath:com/partner4java/spring/App.class</value>
	</property>
</bean>


11创建Bean后处理器

问题:
你希望在Spring IoC容器中注册自己的插件,在构造期间处理Bean实例。

解决方案:
Bean后处理器允许在初始化回调方法前后进行附加的Bean处理。
Bean后处理器的主要特性是逐个处理IoC容器中的所有Bean实例,而不是单个Bean实例。
一般,Bean后处理器用于检查Bean属性有效性,或者根据特殊条件修改Bean属性。

Bean后处理器的基本要求是实现BeanPostProcessor接口。
你可以实现postProcessBeforeInitialization()和postProcessAfterInitialization()方法,在初始化回调方法前后处理所有Bean。
然后,Spring将在调用初始化回调方法前后向这两个方法传递每个Bean实例。
步骤如下:
1、构造程序或者工厂方法创建Bean实例。
2、为Bean属性设置值和Bean引用。
3、调用感知接口中定义的设置方法。
4、将Bean实例传递给每个Bean前置处理器中的postProcessBeforeInitialization方法。
5、调用初始化回调方法。
6、讲Bean实例传递给每个Bean后处理器中的postProcessAfterInitialization方法。
7、Bean准备就绪,可以使用。
8、容器关闭时,调用析构回调方法。
使用Bean工厂为IoC容器时,Bean后处理器只能编程注册,更准确的讲是通过addBeanPostProcessor()方法注册。
但是,如果你使用一个应用上下文,注册将很简单,只要在Bean配置文件中声明处理器实例,他就会自动注册。


工作原理:
public class LogBeanPostProcessor implements BeanPostProcessor {

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println(beanName + " say hello world!");
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println(beanName + " say good buy!");
		return bean;
	}

}

<!-- 要在应用上线文中注册一个Bean后处理器,只要在Bean配置文件中声明他的一个实例就可以了。 应用上下文能够自动检测谁实现了BeanPostProcessor接口,并且注册他一处理容器中的所有其他Bean实例 -->
<bean class="com.partner4java.spring.postprocess.LogBeanPostProcessor" />

<bean id="helloResourceLoader" class="com.partner4java.spring.resource.HelloResourceLoader"
	init-method="showResource" />
		
如果以配置文件的格式设置init-method,对BeanPostProcesser的执行没有什么威胁,BeanPostProcesser还是会先执行。
但是如果,以@PreDestroy和@PostConstruct的形式,BeanPostProcesser讲不能正常工作,因为BeanPostProcesser的默认优先级低于CommonAnnotationBeanPostProcesser。
不过可以同时实现PriorityOrdered接口来指定执行顺序。		


12外部化Bean配置

问题:
在配置文件中配置Bean时,你必须记住,讲部署细节如文件路径、服务器地址、用户名和密码与Bean配置混在一起是不好的做法。
通常,Bean配置由应用开发人员编写,而部署细节则是部署人员或者系统管理员的事情。

解决方案:
Spring有一个名为PropertyPlaceholderConfigurer的Bean工厂后处理器,
用来将部分Bean配置外部化为一个属性文件。你可以在Bean配置文件中使用${var}形式的变量,
PropertyPlaceholderConfigurer讲从属性文件中加载属性并且用他们替代变量。

Bea工厂后处理器与Bean后处理器之间的不同在他的目标是IoC容器--Bean工厂或者应用上下文,而不是Bean实例。
Bean工厂后处理器将在IoC容器加载Bean配置之后、Bean实例创建之前生效,他的典型作用是在Bean实例化之前修改Bean配置。
Spring有多个Bean工厂后处理器供你使用。在实战中,你很少与必要编写自己的Bean工厂后处理器。

工作原理:
方式一:
具体指定外部Bean配置类
DBConfig.properties:
DB.name=test

public class DBConfig {
	private String name;

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "DBConfig [name=" + name + "]";
	}
	
}


<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	<property name="location">
		<value>classpath:DBConfig.properties</value>
	</property>
</bean>

<bean id="dbConfig" class="com.partner4java.spring.config.DBConfig">
	<property name="name" value="${DB.name}"/>
</bean>

第二种:
简单的方式
<context:property-placeholder location="classpath:DBConfig.properties"/>


13解析文本消息

问题:
对于支持国际化的应用来说,为不同地区解析文本消息的能力是必要的。

解决方案:
Spring应用上下文能够按照关键字为目标地区解析文本消息。一般来说,一个地区的消息应该存储在一个独立的属性文件中,这个属性文件称作资源包(Resource bundle)。
MessageSource是定义多种消息解析方法的接口。ApplicationContext接口扩展了这个接口,使用所有应用上下文能够解析文本消息。
应用上下文将消息解析委派给名为messageSource的Bean。ResourceBundleMessageSource最常见的MessageSource实现,他从资源包中解析不同地区的消息。

工作原理:
方式一:
message_en_US.properties:
shopping.wife=gaofumei beatu
shopping.age={0} oh

<bean id="messageSource"
	class="org.springframework.context.support.ResourceBundleMessageSource">
	<property name="basename">
		<value>message</value>
	</property>
</bean>

@Test
public void testAware() throws InterruptedException{
	System.out.println(applicationContext.getMessage("shopping.wife", null, Locale.US));
	System.out.println(applicationContext.getMessage("shopping.age", new Object[]{18}, Locale.US));
}

后台打印:
gaofumei beatu
18 oh


14使用应用事件进行通信

问题:
在组件之间的典型通信模式中,发送者必须定位接受者,以便调用接受者之上的方法。
在这种情况下,发送者组件必须了解接收者组件。这种通信直接而简单,但是发送者和接受者组件紧密耦合。


使用IoC容器时,你的组件可以通过接口而不是实现进行通信。这种通信模式有助于减少耦合。
但是,只有在发送者组件必须与一个接受者通信时有效。当发送者必须与多个接受者通信时,必须逐个调用接收者。


解决方案:
Spring的应用上下文支持基于事件的Bean间通信。
在基于事件的通信模式中,发送者组件只要发布一个事件而不需要知道接收者。
实际上,可以有多于一个接收者组件。
而且,接收者不需要知道是谁发布了事件,可以同时监听不同发送者的多个事件。
这样,发送者和接收者组件是低耦合的。


在Spring中,所有事件类都必须扩展ApplicationEvent类。这样,任何Bean都可以调用应用时间发布者的publishEvent()方法,发布一个事件 。
对于监听某些事件的Bean来说,必须实现ApplicationListener接口,并在onApplicationEvent()方法中处理事件。
实际上,Spring将通知所有事件的监听者,这样你必须自己过滤事件。但是,如果使用类属,Spring将只分发匹配类属参数的消息。


工作原理:
(jdk里面的观察者模式也挺成熟的)


15在Spring中注册属性编辑器

问题:
属性编辑器是JavaBeans API的一项功能,用于属性值与文本值互相转换。
每个属性编辑器仅用于某一类属性。你可以希望采用属性编辑器来简化Bean配置。

解决方案:
Spring IoC容器支持使用属性编辑器帮助Bean配置。
例如,使用java.net.URL类型的属性编辑器,可以指定用于URL类型属性的URL字符串。
Spring会自动的将这个URL字符串转换为一个URL对象,注入你的属性中。
Spring自带多种用于转换常见类型Bean属性的属性编辑器。

一般来说,你应该在Spring IoC容器中注册属性编辑器,然后才能使用它。
CustomEditorConfigurer是作为Bean工厂后处理器来实现的,用于在任何Bean实例化之前注册你的自定义属性编辑器。

工作原理:
就是先写一个编辑器,然后注册,然后自动使用。
除了CustomDateEditor之外,Spring自带多个转换常见数据类型的属性编辑器,
例如CustomNumberEditor、ClassEditor、FileEditor、LocaleEditor、StringArrayPropertyEditor和URLEditor。
可查看包:org.springframework.beans.propertyeditors

public class User {
	private String username;
	private Date birthday;
...

<bean id="dateEditor"
	class="org.springframework.beans.propertyeditors.CustomDateEditor">
	<!-- DateFormat对象作为其第一个构造程序参数 -->
	<constructor-arg>
		<bean class="java.text.SimpleDateFormat">
			<constructor-arg value="yyyy-MM-dd" />
		</bean>
	</constructor-arg>
	<!-- 表示该编辑器是否允许空值 -->
	<constructor-arg value="true"/>
</bean>

<!-- 必须进行注册 -->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
	<property name="customEditors">
		<map>
			<entry key="java.util.Date">
				<ref local="dateEditor"/>
			</entry>
		</map>
	</property>
</bean>

<bean id="user" class="com.partner4java.spring.editor.User">
	<property name="username" value="gaofumei"/>
	<property name="birthday" value="2012-10-10"/>
</bean>



16创建自定义属性编辑器

问题:
除了注册内建的属性编辑器之外,你可能希望编写自定义的属性编辑器,转换你自定义数据类型。

解决方案:
你可以实现java.beans.PropertyEditor实例或者扩展便利的支持类java.beans.PropertyEditorSupport,编写自定义的属性编辑器。

工作原理:
首先实现自己的编辑器,然后注册编辑器
public class UserEditor extends PropertyEditorSupport {

	@Override
	public String getAsText() {
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		User user = (User) getValue();

		return user.getClass().getName() + "," + user.getUsername() + ","
				+ dateFormat.format(user.getBirthday());
	}

	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		String[] parts = text.split(",");
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		
		try {
			User user = (User)Class.forName(parts[0]).newInstance();
			user.setUsername(parts[1]);
			user.setBirthday(dateFormat.parse(parts[2]));
			
			setValue(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

<!-- 必须进行注册 -->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
	<property name="customEditors">
		<map>
			<entry key="com.partner4java.spring.editor.User">
				<bean class="com.partner4java.spring.editor.UserEditor"/>
			</entry>
		</map>
	</property>
</bean>

<bean id="userChild" class="com.partner4java.spring.editor.UserChild">
	<property name="user">
		<value>com.partner4java.spring.editor.User,gaofumei,2012-01-02</value>
	</property>
</bean>

@Test
public void testAware() throws InterruptedException{
	System.out.println(applicationContext.getBean("userChild"));
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值