Spring中实现动态工厂主要依赖< bean > 标签的factory-bean 和factory-method属性,我们要想实现动态工厂功能,就需要在自定义BeanDefined中添加这两个属性:
public class BeanDefined {
private String beanId;
private String classPath;
//和Spring一样,默认是单例
private String beanScope = "singleton";
//自定义工厂类
private String factoryBean;
//自定义工厂方法
private String factoryMethod;
get/set省略......
实现自定义工厂,所以手写一个简单的创建对象的工厂类:
public class MyBeanFactory {
public User getInstance(){
User user = new User();
System.out.println("调用自定义的BeanFactory");
return user;
}
}
通过Spring实现自定义工厂时,需要注册到 Spring 容器中,同样的,我们自己实现的动态工厂的功能也需要把自定义工厂类添加到我们对应的容器中,也就是 BeanFactory 类中的 springIoc 集合中,这里我们只对 scope 属性为 prototype 的情况进行的拓展:
public Object getFactoryBean(String beanId) throws Exception{
Object instance = null;
for (BeanDefined bean: beanDefinedList){
if (beanId.equals(bean.getBeanId())){
String classPath = bean.getClassPath();
if ("singleton".equals(bean.getBeanScope())){
instance = springIoc.get(beanId);
} else {
if (bean.getFactoryBean() != null && bean.getFactoryMethod() != null){
//实例化自定义工厂
Object factoryObject = springIoc.get(bean.getFactoryBean());
//调用对象实例化方法
Method method = factoryObject.getClass().getDeclaredMethod(bean.getFactoryMethod(), null);
method.setAccessible(true);
instance = method.invoke(factoryObject, null);
} else {
instance = Class.forName(classPath).newInstance();
}
}
}
}
return instance;
}
测试类代码中实际调用我们刚刚自定义好的动态工厂:
@Test
public void testMyBeanFactory() throws Exception {
//注册bean
BeanDefined beanDefined = new BeanDefined();
beanDefined.setBeanId("user");
beanDefined.setClassPath("com.lks.bean.User");
beanDefined.setBeanScope("prototype");
beanDefined.setFactoryBean("myBeanFactory");
beanDefined.setFactoryMethod("getInstance");
//注册自定工厂,类似Spring中在配置文件中注册自定义工厂
BeanDefined myBeanFactory = new BeanDefined();
myBeanFactory.setBeanId("myBeanFactory");
myBeanFactory.setClassPath("com.lks.util.MyBeanFactory");
List<BeanDefined> beanDefineds = new ArrayList<BeanDefined>(16);
beanDefineds.add(myBeanFactory);
beanDefineds.add(beanDefined);
//声明BeanFactory,类似于Spring中的ApplicationContext
BeanFactory factory = new BeanFactory(beanDefineds);
//实际调用
User user = (User) factory.getFactoryBean("user");
System.out.println(user);
User user2 = (User) factory.getFactoryBean("user");
System.out.println(user2);
}
先是注册bean,设置factory-bean 和factory-method属性,然后注册自定义工厂,类似在Spring配置文件中配置自定义工厂。