import com.rainbowsea.Bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
@org.junit.Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
}
package com.rainbowsea.Bean;
/**
* 特点:它是简单工厂模式(静态工厂模式),是静态的一个方法
*
*/
public class UserFactory {
// 工厂方法模式中的具体工厂角色中的方法是:实例方法
public User get() {
// 相同点是和静态工厂方法模式是一样的:都是我们自己程序员 new 的。
// 然后交给 Spring框架管理
return new User();
}
}
import com.rainbowsea.Bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
@org.junit.Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
User user = applicationContext.getBean("userBean", User.class);
System.out.println(user);
}
}
这里我们定义了一个 UserFactory 产生 User 的对象的工厂类,同时实现implements FactoryBean 该接口。
package com.rainbowsea.Bean;
import org.springframework.beans.factory.FactoryBean;
/**
* 特点:它是简单工厂模式(静态工厂模式),是静态的一个方法
*
*/
public class UserFactory implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
// 本质上还是我们程序员自己 new ()出来的,并不是 Spring 弄出来
return new User();
}
// 这个方法可以不用管它。
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return true; // 单例
// false 多例
}
}
第三步:在Spring配置文件中配置FactoryBean
由于我们这个public class UserFactory implements FactoryBean 生产 User 的工厂实现了 FactoryBean 接口,Spring 已经是知道,我们需要调用的是哪个对象当中的哪个方法,从而获取对应的 user Bean对象了。所以对应其中的 spinrg.xml 只需要简单的配置一下,即可。
package com.rainbowsea.test;
import com.rainbowsea.Bean.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
@org.junit.Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring6.xml");
User user = applicationContext.getBean("userFactory", User.class);
System.out.println(user);
}
}
原因是,在Spring 如果将 Date 作为简单类型进行注入的话,需要特定的时间格式,才能注入成功。
准备工作:定义一个 Bean 类,同时其中含有一个 Date 类型的属性值。
package com.rainbowsea.Bean.myDate;
import java.util.Date;
public class Vip {
private Date birth;
public Vip(Date birth) {
this.birth = birth;
}
public Vip() {
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Vip{" +
"birth=" + birth +
'}';
}
}
演示如下:
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'vipBean' defined in class path resource [spring2.xml]: Failed to convert property value of type 'java.lang.String' to required type 'java.util.Date' for property 'birth'; Cannot convert value of type 'java.lang.String' to required type 'java.util.Date' for property 'birth': no matching editors or conversion strategy found
对应Spring当中的 Date 作为简单类型的注入,需要用如下它美国的格式时间格式,才能被识别为 Date 类型。特殊格式如下:
Mon Apr 29 20:03:58 CST 2024
虽然转化成功了,但是这个格式,对于我们国人来说,不太友好,而且也不好记忆。
所以为了将Date 类型转化为我们国人友好的类型的格式,我们就需要将 Date 定义为 复杂类型
进行 ref 注入。但是怎样将 Date 作为复杂类型注入的同时又可以转换为我们需要的格式呢。——这就需要用到上面我们所学习的通过 FactoryBean接口 获取 Bean 对象了。其实呢,上面第二种方式,第三种方式,第四种方式都是可以实现的。但是第四种方式比较简化,我们这里就用第四种方式来解决。这个问题。
第一步: 定义一个含有 Date 类型的类,就还是使用上面哪个 Vip 类吧
第二步: 创建一个用于生产我们所需要的格式的 Date的工厂 同时该工厂又实现了 implements FactoryBean 接口。告诉Spring框架,调用其中的哪个对象当中的哪个方法,获取到我们所需要的 Date 对象。
package com.rainbowsea.Bean.myDate;
import org.springframework.beans.factory.FactoryBean;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Date 工厂模式
* DateFactoryBean 这个工厂Bean 协助我们Spring 创建这个普通的Bean;Date
*/
public class DateFactor implements FactoryBean<Date> {
// 这个 String字符串类型,作为我们Date类型,进行一个转换
private String strDate;
public DateFactor() {
}
public DateFactor(String strDate) {
this.strDate = strDate;
}
public String getStrDate() {
return strDate;
}
public void setStrDate(String strDate) {
this.strDate = strDate;
}
@Override
public Date getObject() throws Exception {
// 通过 SimpleDateFormat 来自定义我们的 Date 的日期时间类型的格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
// 通过在 spring.xml 对DateFactor类当中的 String strDate 属性进行赋值
Date date = simpleDateFormat.parse(this.strDate); // 将字符串类型转换为 Date 日期时间类型
return date; // 转换后返回 Date 类型,进行一个赋值操作
}
@Override
public Class<?> getObjectType() {
return null;
}
@Override
public boolean isSingleton() {
return true; // 单例 false 多例
}
}
上述代码的核心代码片段讲解:
// 这个 String字符串类型,作为我们Date类型,进行一个转换
private String strDate;
public Date getObject() throws Exception {
// 通过 SimpleDateFormat 来自定义我们的 Date 的日期时间类型的格式
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
// 通过在 spring.xml 对DateFactor类当中的 String strDate 属性进行赋值
Date date = simpleDateFormat.parse(this.strDate); // 将字符串类型转换为 Date 日期时间类型
return date; // 转换后返回 Date 类型,进行一个赋值操作
}
通过定义一个Date 类型的工厂类 生产出,我们需要的格式的 Date 类型。
首先在其 DateFactor 工厂类当中,创建一个 String strDate 用于我们传入日期时间,再通过 new SimpleDateFormat("yyyy-MM-dd") 来定义我们的Date 日期时间类型的格式。通过Date date = simpleDateFormat.parse(this.strDate); 将字符串类型转换为 Date 日期时间类型。最后返回一个我们所需要的格式的 Date 类型的日期时间类型。
核心要素就是:通过一个(这里时生产我们所需格式的 Date 类型的)工厂类实现 FactoryBean接口,被称为“工厂Bean”。“工厂Bean(通过工厂上的方法返回一个对应的 Bean(这里时 Date ) 对象)”是一种特殊的Bean。获取到对应 Date 后,再作为 复杂类型作为其他类上的属性的值存在。
对应Spring当中的 Date 作为简单类型的注入,需要用如下它美国的格式时间格式,才能被识别为 Date 类型。
核心要素就是:通过一个(这里时生产我们所需格式的 Date 类型的)工厂类实现 FactoryBean接口,被称为“工厂Bean”。“工厂Bean(通过工厂上的方法返回一个对应的 Bean(这里时 Date ) 对象)”是一种特殊的Bean。获取到对应 Date 后,再作为 复杂类型作为其他类上的属性的值存在。