学习Spring第三天
JdbcTemplate
原始的jdbc
public void insert(Customer customer) {
String sql = "INSERT INTO customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, customer.getCusId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge());
ps.executeUpdate();
ps.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
改用JdbcTemplate方法
private DataSource dataSource;
private JdbcTemplate jdbcTemplate;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
@Override
public void insert(Customer customer) {
String sql = "INSERT INTO customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
jdbcTemplate = new JdbcTemplate(dataSource);
jdbcTemplate.update(sql,customer.getCusId(),customer.getName(),customer.getAge());
}
瞬间感觉代码量少了很多,对比之前复杂的原生操作,jdbctemplate还是很容易理解的
JdbcDaoSupport
public class JdbcCustomerDao extends JdbcDaoSupport implements CustomerDao {
@Override
public void insert(Customer customer) {
String sql = "INSERT INTO customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
getJdbcTemplate().update(sql, customer.getCusId(), customer.getName(), customer.getAge());
}
@Override
public Customer findByCustomerId(int cusId) {
String sql = "SELECT * FROM customer WHERE CUST_ID = ?";
List<Customer> customers = new ArrayList<>();
getJdbcTemplate().query(sql, new Object[]{cusId}, new RowCallbackHandler() {
Customer customer;
@Override
public void processRow(ResultSet rs) throws SQLException {
customer = new Customer(rs.getInt("CUST_ID"), rs.getString("NAME"), rs.getInt("AGE"));
customers.add(customer);
}
});
return customers.get(0);
}
}
自定义RowMapper
JdbcTemplate推荐使用自定义的RowMapper进行字段的映射
我们自定义一个Mapper
package com.demo.Mapper;
import com.demo.Model.Customer;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.lang.Nullable;
import java.sql.ResultSet;
import java.sql.SQLException;
public class CustomerRowMapper implements RowMapper<Customer> {
@Nullable
@Override
public Customer mapRow(ResultSet rs, int rowNum) throws SQLException {
Customer customer = new Customer();
customer.setCusId(rs.getInt("CUST_ID"));
customer.setName(rs.getString("NAME"));
customer.setAge(rs.getInt("AGE"));
return customer;
}
}
FindByCustomerId方法可以重写了
@Override
public Customer findByCustomerId(int cusId) {
String sql = "SELECT * FROM customer WHERE CUST_ID = ?";
List<Customer> customers = new ArrayList<>();
customers = getJdbcTemplate().query(sql, new Object[]{cusId}, new RowMapperResultSetExtractor<>(new CustomerRowMapper()));
return customers.get(0);
}
运行结果也是不变的.
如果我们想限制数量可以在RowMapperResultSetExtractor加上第二的参数,表示查询的数量,为1时则为单个实体类,其他的情况下是该实体类的List集合
Example
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
RowMapper rowMapper = new UserRowMapper();
List allUsers = (List) jdbcTemplate.query(
"select * from user",
new RowMapperResultSetExtractor(rowMapper, 10));
User user = (User) jdbcTemplate.queryForObject(
"select * from user where id=?", new Object[] {id},
new RowMapperResultSetExtractor(rowMapper, 1));
BeanPropertyRowMapper
当Entity属性的名称和数据表的字段名称一致的时候可以用BeanPropertyRowMapper来进行映射
customers = getJdbcTemplate().query(sql, new Object[]{cusId}, new BeanPropertyRowMapper<>(Customer.class));
batchUpdate的用法
当我们需要批量操作(同时插入多个值),重复调用相同的方法会显得相当麻烦,这时我们可以使用batchUpdate方法
我们写一个批量插入的方法
public void insertBatch(List<Customer> customers) {
String sql = "INSERT INTO customer(CUST_ID,NAME,AGE) VALUES(?,?,?)";
getJdbcTemplate().batchUpdate(sql, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
Customer customer = customers.get(i);
ps.setInt(1, customer.getCustId());
ps.setString(2, customer.getName());
ps.setInt(3, customer.getAge());
}
@Override
public int getBatchSize() {
return customers.size();
}
});
}
这里使用了jdbcTemplate的batchUpdate方法,通过第二个参数设置字段映射.当你的字段与数据库字段一致时可以省略
记录一下JdbcDaoSupport的用法
原生sql语句执行
jdbcTemplate.execute("CREATE TABLE USER (user_id integer, name varchar(100))");
如果是UPDATE或INSERT,可以用update()方法
jdbcTemplate.update("INSERT INTO USER VALUES('"
+ user.getId() + "', '"
+ user.getName() + "', '"
+ user.getSex() + "', '"
+ user.getAge() + "')");
带参数的更新
jdbcTemplate.update("UPDATE USER SET name = ? WHERE user_id = ?", new Object[] {name, id});
jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)", new Object[] {user.getId(), user.getName(), user.getSex(), user.getAge()});
使用JdbcTemplate进行查询时,使用queryForXXX()等方法
int count = jdbcTemplate.queryForInt("SELECT COUNT(*) FROM USER");
String name = (String) jdbcTemplate.queryForObject("SELECT name FROM USER WHERE user_id = ?", new Object[] {id}, java.lang.String.class);
使用iterator迭代器查询
List rows = jdbcTemplate.queryForList("SELECT * FROM USER");
List rows = jdbcTemplate.queryForList("SELECT * FROM USER");
Iterator it = rows.iterator();
while(it.hasNext()) {
Map userMap = (Map) it.next();
System.out.print(userMap.get("user_id") + "\t");
System.out.print(userMap.get("name") + "\t");
System.out.print(userMap.get("sex") + "\t");
System.out.println(userMap.get("age") + "\t");
}
在update或者query时还可以通过callback回调设置你的字段
final String id = user.getId();
final String name = user.getName();
final String sex = user.getSex() + "";
final int age = user.getAge();
jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)",
new PreparedStatementSetter() {
public void setValues(PreparedStatement ps) throws SQLException {
ps.setString(1, id);
ps.setString(2, name);
ps.setString(3, sex);
ps.setInt(4, age);
}
});
final User user = new User();
jdbcTemplate.query("SELECT * FROM USER WHERE user_id = ?",
new Object[] {id},
new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
user.setId(rs.getString("user_id"));
user.setName(rs.getString("name"));
user.setSex(rs.getString("sex").charAt(0));
user.setAge(rs.getInt("age"));
}
});
RowMapper
class UserRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int index) throws SQLException {
User user = new User();
user.setId(rs.getString("user_id"));
user.setName(rs.getString("name"));
user.setSex(rs.getString("sex").charAt(0));
user.setAge(rs.getInt("age"));
return user;
}
}
public List findAllByRowMapperResultReader() {
String sql = "SELECT * FROM USER";
return jdbcTemplate.query(sql, new RowMapperResultReader(new UserRowMapper()));
}
public User getUser(final String id) throws DataAccessException {
String sql = "SELECT * FROM USER WHERE user_id=?";
final Object[] params = new Object[] { id };
List list = jdbcTemplate.query(sql, params, new RowMapperResultReader(new UserRowMapper()));
return (User) list.get(0);
}
Spring自动装配Beans
Spring对于Bean采用自动装配(AueoWire)机制
分为五种:
1、no 省缺情况下,通过ref属性绑定
2、byName 根据属性名自动装配 如果一个property的name和另一个bean的id相同,Spring将会自动装配
3、byType 根据属性数据类型自动装配 如果一个property的属性和另一个bean的数据类型相同,Spring将会自动装配
4、construtor 对于构造函数的属性使用byType方式
5、autodetect 如果找到默认的构造函数采用“自动装配使用构造”,否则使用“按类型装配”
这里演示使用constructor的方式
Person Model
package com.demo.Model;
public class Person {
private String name;
private int age;
private String address;
public Person() {
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Customer Model
package com.demo.Model;
public class Customer {
private Person person;
public Customer(Person person) {
this.person = person;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
在resources中加入配置文件Spring-Beans.xml
<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-4.0.xsd">
<bean id="customer" class="com.demo.Model.Customer" autowire="constructor"/>
<bean id="person" class="com.demo.Model.Person">
<property name="name" value="RenBuRuGu"/>
<property name="age" value="20"/>
<property name="address" value="JiangSu NanJing"/>
</bean>
</beans>
测试类App
package com.demo;
import com.demo.Model.Customer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Beans.xml");
Customer customer = context.getBean(Customer.class);
System.out.println(customer.getPerson().getAddress());
System.out.println(customer.getPerson().getAge());
System.out.println(customer.getPerson().getName());
}
}
运行结果如下:
@AutoWired字段
首先在beans中加入
<context:annotation-config />
或者
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
@AutoWired注解可以在属性、setter方法、或者构造方法中使用
Spring-Beans.xml
<context:annotation-config/>
<bean id="customer" class="com.demo.Model.Customer"/>
<bean id="person" class="com.demo.Model.Person">
<property name="name" value="RenBuRuGu"/>
<property name="age" value="20"/>
<property name="address" value="JiangSu NanJing"/>
</bean>
setter方法
public class Customer {
private Person person;
public Person getPerson() {
return person;
}
@Autowired
public void setPerson(Person person) {
this.person = person;
}
}
属性
public class Customer {
@Autowired
private Person person;
public Person getPerson() {
return person;
}
}
构造方法
public class Customer {
private Person person;
@Autowired
public Customer(Person person) {
this.person = person;
}
public Person getPerson() {
return person;
}
}
@Qualifier
当自动装载的bean有冲突时,就可以用@Qualifier属性
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Customer {
@Autowired
@Qualifier("personA")
private Person person;
}
JavaConfig
我们之前注册bean都是通过xml注册的,形式如下:
<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-4.0.xsd">
<bean id="helloBean" class="com.demo.Model.HelloBean">
<property name="id" value="1"/>
<property name="content" value="Hello Spring"/>
</bean>
</beans>
实体类代码如下:
package com.demo.Model;
public class HelloBean {
private int id;
private String content;
public void setId(int id) {
this.id = id;
}
public void setContent(String content) {
this.content = content;
}
public void print() {
System.out.println("HelloBean:[ " + id + " " + content + " ]");
}
}
我们写一个测试类来测试一下:
package com.demo;
import com.demo.Model.HelloBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Beans.xml");
HelloBean helloBean = context.getBean(HelloBean.class);
helloBean.print();
}
}
输出结果如下:
我们也可以通过Spring注解的方式来用java代码完成配置
package com.demo;
import com.demo.Model.HelloBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean(name = "helloBean")
public HelloBean helloBean(){
HelloBean bean = new HelloBean();
bean.setContent("Hello Spring");
bean.setId(1);
return bean;
}
}
在Spring中,配置文件必须用configuration注解,相应的bean用@Bean注入
相应的修改一下App测试类
import com.demo.Model.HelloBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
HelloBean helloBean = context.getBean(HelloBean.class);
helloBean.print();
}
}
输出结果完全一致
@Import的使用
通常我们会把不同功能的配置文件分开到不同的xml中书写,然后统一在一个xml中导入进来,就像下面:
<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-2.5.xsd">
<import resource="config/customer.xml"/>
<import resource="config/scheduler.xml"/>
</beans>
我们可以使用Import注解来完成相同的功能
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({ CustomerConfig.class, SchedulerConfig.class })
public class AppConfig {
}
我们分别创建两个实体类CustomerBo和SchedulerBo
package com.demo.Model;
public class CustomerBo {
public void printMsg(String msg) {
System.out.println("CustomerBo: " + msg);
}
}
package com.demo.Model;
public class SchedulerBo {
public void printMsg(String msg) {
System.out.println("SchedulerBo: " + msg);
}
}
接着创建相应的配置文件
package com.demo.Config;
import com.demo.Model.CustomerBo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CustomerConfig {
@Bean(name = "customer")
public CustomerBo customerBo(){
return new CustomerBo();
}
}
package com.demo.Config;
import com.demo.Model.SchedulerBo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SchedulerConfig {
@Bean(name = "scheduler")
public SchedulerBo schedulerBo() {
return new SchedulerBo();
}
}
然后在AppConfig中引用
package com.demo;
import com.demo.Config.CustomerConfig;
import com.demo.Config.SchedulerConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@Import({CustomerConfig.class, SchedulerConfig.class})
public class AppConfig {
}
我们在测试类中就可以正常获取到这两个实体类了
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
CustomerBo customerBo = context.getBean(CustomerBo.class);
SchedulerBo schedulerBo = context.getBean(SchedulerBo.class);
customerBo.printMsg("hello Spring");
schedulerBo.printMsg("hello Spring");
}
}
运行结果如下:
DI注入的小问题
我们通过在xml中书写配置文件进行DI注入,有两种方式:setter函数注入和构造函数注入
setter函数注入:用ref引用相应的bean
构造函数注入:用<constructor-arg>
标签
如果存在多个构造函数,为了避免歧义,需要手动指定数据类型
<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-2.5.xsd">
<bean id="CustomerBean" class="com.yiibai.common.Customer">
<constructor-arg type="java.lang.String">
<value>yiibai</value>
</constructor-arg>
<constructor-arg type="java.lang.String">
<value>188</value>
</constructor-arg>
<constructor-arg type="int">
<value>28</value>
</constructor-arg>
</bean>
</beans>
Spring中对Bean的引用
有两种方式bean和local
<ref>
提供了如下几方面的属性 :
1)bean: 在当前 Spring XML 配置文件中,或者在同一 BeanFactory(ApplicationContext) 中的其他 JavaBean 中 .
2)local: 在当前 Spring XML 配置文件中 . 其依赖的 JavaBean 必须存在于当前 Spring XML配置文件中 . 如果借助于 Spring IDE, 则在编译期可以对其依赖的 JavaBean 进行验证。基于 local 方式,开发者能够使用到 XML 本身提供 的优势,而进行验证。
3)parent: 用于指定其依赖的父 JavaBean 定义。
local属性在Spring 4.x中被废弃
<bean id="OutputHelper" class="com.yiibai.output.OutputHelper">
<property name="outputGenerator" >
<ref local="CsvOutputGenerator"/>
</property>
</bean>
<bean id="OutputHelper" class="com.yiibai.output.OutputHelper">
<property name="outputGenerator" >
<ref bean="CsvOutputGenerator"/>
</property>
</bean>
在xml中注入属性有三种方式 正常模式、快捷方式和P模式
正常模式(4.x不推荐使用)
<bean id="helloBean" class="com.demo.Model.CustomerBo">
<property name="content">
<value>Hello World</value>
</property>
</bean>
快捷方式(value属性)
<bean id="helloBean" class="com.demo.Model.CustomerBo">
<property name="content" value="Hello World"/>
</bean>
P模式(value和value-ref两种模式 分别表示直接赋值和引用)
<bean id="helloBean" class="com.demo.Model.CustomerBo" p:content="hello world"/>
Spring Bean的作用域
Spring中Bean的作用域有两种 singleton(默认)单例模式和prototype 原型模式
生命作用域的方式很简单,至于要在xml的bean中使用scope
属性即可
我们还可以通过@Scope注解的方式来实现相同的效果
@Service
@Scope("prototype")
public class CustomerService
{
String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
需要在xml中开启自动扫描组件功能
<context:component-scan base-package="com.yiibai.customer" />
Spring中注册List Map Set Properties等集合
Spring中支持对这些集合类的注册和使用,下面是例子
创建两个实体类Person和Customer
Person.java
package com.demo.Model;
public class Person {
private String name;
private String address;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "[ name: " + name + "address: " + address + "age: " + age + " ]";
}
}
Customer.java
package com.demo.Model;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Customer {
private List<Object> lists;
private Set<Object> sets;
private Map<Object, Object> maps;
private Properties props;
public void setLists(List<Object> lists) {
this.lists = lists;
}
public void setSets(Set<Object> sets) {
this.sets = sets;
}
public void setMaps(Map<Object, Object> maps) {
this.maps = maps;
}
public void setProps(Properties props) {
this.props = props;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append("list:\n");
for (Object o : lists) {
buffer.append(o.toString() + "\n");
}
buffer.append("set:\n");
for (Object o : sets) {
buffer.append(o.toString() + "\n");
}
buffer.append("map:\n");
for (Object o : maps.keySet()) {
buffer.append("key: " + o.toString() + " value: " + maps.get(o).toString() + "\n");
}
buffer.append("properties:\n");
for (Object o : props.keySet()) {
buffer.append("key: " + o.toString() + " value: " + props.get(o).toString() + "\n");
}
return buffer.toString();
}
}
我们可以在xml中去注册这些属性值
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
<bean id="customer" class="com.demo.Model.Customer">
<property name="lists">
<list>
<value>1</value>
<ref bean="person"/>
<bean class="com.demo.Model.Person"
p:name="RenBuRuGu123"
p:address="JiangSu NanJing"
p:age="22"/>
</list>
</property>
<property name="maps">
<map>
<entry key="1" value="1"/>
<entry key="2" value-ref="person"/>
<entry key="hello">
<bean class="com.demo.Model.Person"
p:name="RenBuRuGu"
p:address="JiangSu NanJing"
p:age="20"/>
</entry>
</map>
</property>
<property name="props">
<props>
<prop key="admin">Admin@123</prop>
<prop key="support">support@gmail.com</prop>
</props>
</property>
<property name="sets">
<set>
<set>
<value>1</value>
<ref bean="person"/>
<bean class="com.demo.Model.Person">
<property name="name" value="Test Set"/>
<property name="address" value="Hainan Haikou"/>
<property name="age" value="28"/>
</bean>
</set>
</set>
</property>
</bean>
<bean id="person" class="com.demo.Model.Person"
p:name="RenBuRuGu"
p:address="JiangSu NanJing"
p:age="20"/>
</beans>
测试类:
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Spring-Beans.xml");
Customer customer = context.getBean(Customer.class);
System.out.println(customer);
}
}
运行结果如下:
自定义List类型
如果想要返回的List是ArrayList数据类型的 你有两种方式去实现它 ListFactoryBean 和 util:list
分别举个例子
ListFactoryBean方式
<property name="lists">
<bean class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="targetListClass" value="java.util.ArrayList"/>
<property name="sourceList">
<list>
<value>1</value>
<ref bean="person"/>
<bean class="com.demo.Model.Person"
p:name="RenBuRuGu123"
p:address="JiangSu NanJing"
p:age="22"/>
</list>
</property>
</bean>
</property>
通过targetListClass指定List的数据类型,sourceList包裹原list数据
util:list方式
<util:list list-class="java.util.ArrayList">
<value>1</value>
<ref bean="person"/>
<bean class="com.demo.Model.Person"
p:name="RenBuRuGu123"
p:address="JiangSu NanJing"
p:age="22"/>
</util:list>
效果完全一样,个人觉得这种方式比较简便
- MapFactoryBean和SetFactoryBean用法完全相同,不做过多介绍…
Spring注入日期类型的数据
1、通过factoryBean的方式
<bean id="dateFormat" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd"/>
</bean>
<bean id="customer" class="com.demo.Model.Customer">
<property name="date">
<bean factory-bean="dateFormat" factory-method="parse">
<constructor-arg value="2015-12-31"/>
</bean>
</property>
</bean>
我们创建一个SimpleDateFormat的Bean然后通过Factory-bean和Factory-method方法调用SimpleDataFormat的prase方法来初始化我们的日期
2、通过CustomDateEditor的方式(反正我不会用,一直报错)
<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-2.5.xsd">
<bean id="dateEditor"
class="org.springframework.beans.propertyeditors.CustomDateEditor">
<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="customer" class="com.yiibai.common.Customer">
<property name="date" value="2015-12-31" />
</bean>
</beans>
<ref local="">
用法好像在4.x中被删除了