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: