spring--工厂方法与FactoryBean(2更)

42 篇文章 0 订阅

spring 引入第三方类时常用方法

1 静态工厂

public class Foo{
   private BarInterface barInterface;
   public Foo(){
   }
}

 

<bean id = "foo" class="...Foo">
   <property name = "barInterface">
      <ref bean="bar"/>
   </property>
</bean>
xml 配置静态工厂方法
<bean id = "bar" class = "...StaticBarInterfaceFactory" factory-method="getInstance">

 

静态工厂定义
public class StaticBarInterfaceFactory{
   public static BarInterface getInstance(){
      return new BarInterfaceImpl();
   }
}

2 动态工厂

动态工厂定义class
public class NonStaticBarInterfaceFactory{
   public BarInterface getInstance(){
       return new BarInterfaceImpl();
   }
}
xml配置
<bean id = "foo" class ="...Foo">
    <property name="barInterface">
       <ref bean="bar"/>
    </property>
</bean>
//动态工厂bean
<bean id="barFactory" class="...NonStaticBarInterfaceFactory"/>
//工厂方法
<bean id="bar" factory-bean="barFactory" factory-method="getInstance"/>

3 FactoryBean--不再需要指定factory-method,实用接口默认的getObject方法获取实例

public interface FactoryBean{
   Object getObject() throws Exception;
   Class getObjectType();
   boolean isSingleton();
}

public class NextDateFactoryBean implements FactoryBean(){
   public Object getObject() throws Exception{
        return new DateTime().plusDays(1);
   }
   public Class getObjectType(){
      return DateTime.class;
   }
   public boolean isSingleton(){
       return false;
   }
}

xml配置
<bean id = "nextDayDateDisplayer" class="...NextDayDateDisplayer">
 
   <property name="dateOfNextDay">
       <ref bean ="nextDayDate">
   </property>

</bean>

<bean id = "nextDayDate" class="...NextDayDateFactoryBean"/>//获取FactoryBean产生的bean

-----------------------------------2 更--------------------------------------

FactoryBean

FactoryBean 适用于 Bean 的创建过程比较复杂的场景,比如数据库连接池的创建。

public interface FactoryBean<T> {
    T getObject() throws Exception;
    Class<T> getObjectType();
    boolean isSingleton();
}
public class Person { 
    private Car car ;
    private void setCar(Car car){ this.car = car;  }  
}

我们假设现在需要创建一个 Person 的 Bean,首先我们需要一个 Car 的实例,我们这里假设 Car 的实例创建很麻烦,那么我们可以把创建 Car 的复杂过程包装起来:

public class MyCarFactoryBean implements FactoryBean<Car>{
    private String make; 
    private int year ;

    public void setMake(String m){ this.make =m ; }

    public void setYear(int y){ this.year = y; }

    public Car getObject(){ 
      // 这里我们假设 Car 的实例化过程非常复杂,反正就不是几行代码可以写完的那种
      CarBuilder cb = CarBuilder.car();

      if(year!=0) cb.setYear(this.year);
      if(StringUtils.hasText(this.make)) cb.setMake( this.make ); 
      return cb.factory(); 
    }

    public Class<Car> getObjectType() { return Car.class ; } 

    public boolean isSingleton() { return false; }
}

我们看看装配的时候是怎么配置的:

<bean class = "com.javadoop.MyCarFactoryBean" id = "car">
  <property name = "make" value ="Honda"/>
  <property name = "year" value ="1984"/>
</bean>
<bean class = "com.javadoop.Person" id = "josh">
  <property name = "car" ref = "car"/>
</bean>

看到不一样了吗?id 为 “car” 的 bean 其实指定的是一个 FactoryBean,不过配置的时候,我们直接让配置 Person 的 Bean 直接依赖于这个 FactoryBean 就可以了。中间的过程 Spring 已经封装好了。

说到这里,我们再来点干货。我们知道,现在还用 xml 配置 Bean 依赖的越来越少了,更多时候,我们可能会采用 java config 的方式来配置,这里有什么不一样呢?

@Configuration 
public class CarConfiguration { 

    @Bean 
    public MyCarFactoryBean carFactoryBean(){ 
      MyCarFactoryBean cfb = new MyCarFactoryBean();
      cfb.setMake("Honda");
      cfb.setYear(1984);
      return cfb;
    }

    @Bean
    public Person aPerson(){ 
    Person person = new Person();
      // 注意这里的不同
    person.setCar(carFactoryBean().getObject());
    return person; 
    } 
}

这个时候,其实我们的思路也很简单,把 MyCarFactoryBean 看成是一个简单的 Bean 就可以了,不必理会什么 FactoryBean,它是不是 FactoryBean 和我们没关系。

 

ref:

https://javadoop.com/post/spring-ioc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自驱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值