FactoryBean,InitializingBean使用

Spring中有两种类型的Bean,一种是普通Bean,另一种是工厂Bean,即FactoryBean。

工厂Bean跟普通Bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂Bean的getObject方法所返回的对象。

使用场景:

1、通过外部对类是否是单例进行控制,该类自己无法感知;

2、对类的创建之前进行初始化的操作,在afterPropertiesSet()中完成。

实例一: 

基础类:Student.java

public class Student { 
    private int    id; 
    private String name; 
 
    public int getId() { 
        return id; 
    } 
 
    public void setId(int id) { 
        this.id = id; 
    } 
 
    public String getName() { 
        return name; 
    } 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 
} 

工厂类:StuFactory.java 


public class StuFactory implements FactoryBean, InitializingBean { 
 
    public void afterPropertiesSet() throws Exception { 
        System.out.println("student class initialized."); 
    } 
 
    public Object getObject() throws Exception { 
        return new Student(); 
    } 
 
    public Class getObjectType() { 
        return Student.class; 
    } 
 
    public boolean isSingleton() { 
        return true; 
    } 
} 

注入到配置文件中:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" 
    xsi:schemaLocation=" 
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd"> 
 
    <bean id="stuFactory" class="com.alibaba.spring.StuFactory"> 
    </bean> 
</beans> 

测试:

public class StuFactoryTest { 
    @Test 
    public void test1() throws Throwable { 
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 
        Student stuFactory1 = (Student) context.getBean("stuFactory"); 
        Student stuFactory2 = (Student) context.getBean("stuFactory"); 
 
        System.out.println(stuFactory1 == stuFactory2); 
    } 
} 

测试结果:

student class initialized. 
true 

【注意】

1、返回的是getObject()中说明的类型,而不是创建工厂的类型,与普通的javabean不一样

2、创建出来的对象是否属于单例由isSingleton中的返回决定。

 

实例二:

FactoryBeanDemo.java

public class FactoryBeanDemo implements FactoryBean { 
    private String name; 
 
    public void setName(String name) { 
        this.name = name; 
    } 
 
    public Object getObject() throws Exception { 
        if ("date".equals(name)) 
            return new Date(); 
        else 
            return new String("这是一个字符串!"); 
    } 
 
    public Class getObjectType() { 
        return "date".equals(name) ? Date.class : String.class; 
    } 
 
    public boolean isSingleton() { 
        return false; 
    } 
} 

配置文件:

<bean name="myFactoryBean" class="com.alibaba.spring.FactoryBeanDemo" /> 
 
<bean name="myFactoryBean1" class="com.alibaba.spring.FactoryBeanDemo"> 
    <property name="name" value="date"></property> 
</bean> 

测试:

Resource res = new ClassPathResource("applicationContext.xml"); 
BeanFactory factory = new XmlBeanFactory(res); 
System.out.println(factory.getBean("myFactoryBean").getClass()); 
System.out.println(factory.getBean("myFactoryBean1").getClass()); 
System.out.println("====================================="); 
System.out.println(factory.getBean("&myFactoryBean").getClass()); 
System.out.println(factory.getBean("&myFactoryBean1").getClass()); 

由此可见,通过使用FactoryBean,我们可以得到不同类型的对象实例。这也就是我们在AOP中通过设置calss为ProxyFactoryBean可以返回不同类型的业务对象的原理。在实际应用中若能灵活使用FactoryBean,则可以给应用程序增加很多的魔幻功能。

测试结果:

class java.lang.String 
class java.util.Date 
===================================== 
class com.alibaba.spring.FactoryBeanDemo 
class com.alibaba.spring.FactoryBeanDemo

一个小窍门:

FactoryBean还藏有一个技巧,也就是在我们实际需要返回FactoryBean实例时,应该怎么办。也就是我们在应用程序中需要通过容器得到一个FactoryBean。此时,需要使用特殊的方式,即在bean的名称前加上一个特殊符号“&”即可。即:System.out.println(factory.getBean("&myFactoryBean").getClass());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值