《step2:tiny Spring IoC学习二》——将bean创建放入工厂
来源:互联网 发布:cnzz数据专家 编辑:程序博客网 时间:2024/06/05 14:21
在上一篇博客《step1:tiny Spring Ioc 学习一最基本的容器BeanFactory》中,bean(HelloWorldService)是通过new初始化好之后再set进去BeanDefinition对象中的,实际使用中,我们希望容器来管理bean的创建。于是我们将bean的初始化工作放入BeanFactory中去。为了保证扩展性,我们使用ExtractInterface的方法,将BeanFactory替换成接口,而使用AbstractBeanFactory和AutowireCapableBeanFactory作为其实现。"AutowireCapable"的意思是“可自动装配的”,在这里的作用是根据jvm已记载的类进行实例化。(为我们后面注入属性做准备)。
同样,demo的类图:
时序图:
根据类图和时序图,我们来看代码的实现:
1·BeanFactory接口
package us.codecraft.tinyioc.factory;/** * Created by 贾丽敏 on 2017/5/29. */import us.codecraft.tinyioc.BeanDefinition;/** * @author * @create 2017-05-29 15:14 **/public interface BeanFactory { //获取bean Object getBean(String name); //注册bean void registerBeanDefinition(String name, BeanDefinition beanDefinition);}2·AbstractBeanFactory抽象类:
package us.codecraft.tinyioc.factory;/** * Created by 贾丽敏 on 2017/5/29. */import us.codecraft.tinyioc.BeanDefinition;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/*** * @author * @create 2017-05-29 15:17**/public abstract class AbstractBeanFactory implements BeanFactory { private Map<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(); public Object getBean(String name) { return beanDefinitionMap.get(name).getBean(); } public void registerBeanDefinition(String name, BeanDefinition beanDefinition) { Object bean = doCreateBean(beanDefinition); beanDefinition.setBean(bean); beanDefinitionMap.put(name,beanDefinition); } //初始化bean protected abstract Object doCreateBean(BeanDefinition beanDefinition);}3·AutowireCapableBeanFactory子类:
package us.codecraft.tinyioc.factory;/** * Created by 贾丽敏 on 2017/5/29. */import us.codecraft.tinyioc.BeanDefinition;/*** 自动初始化bean* @author * @create 2017-05-29 15:23**/public class AutowireCapableBeanFactory extends AbstractBeanFactory { @Override protected Object doCreateBean(BeanDefinition beanDefinition) { try { Object bean = beanDefinition.getBeanClass().newInstance(); return bean; }catch (InstantiationException e){ e.printStackTrace(); }catch (IllegalAccessException e){ e.printStackTrace(); } return null; }}
4·BeanDefinition封装类:
package us.codecraft.tinyioc;/** * Created by 贾丽敏 on 2017/5/29. *//*** * @author * @create 2017-05-29 15:08**/public class BeanDefinition { private Object bean; private Class beanClass; private String beanClassName; public Object getBean() { return bean; } public void setBean(Object bean) { this.bean = bean; } public Class getBeanClass() { return beanClass; } public void setBeanClass(Class beanClass) { this.beanClass = beanClass; } public String getBeanClassName() { return beanClassName; } public void setBeanClassName(String beanClassName) { this.beanClassName = beanClassName; try { //TODO:Class.forName? this.beanClass=Class.forName(beanClassName); }catch (ClassNotFoundException e){ e.printStackTrace(); } }}
5·Bean对象:HelloWorldService类
package us.codecraft.tinyioc;/** * Created by 贾丽敏 on 2017/5/29. *//*** * @author * @create 2017-05-29 10:58**/public class HelloWorldService { public void printHelloWorld(){ System.out.println("hello world"); }}
6·测试类BeanFactoryTest:
package us.codecraft.tinyioc; /** * Created by 贾丽敏 on 2017/5/29. */import org.junit.Test;import us.codecraft.tinyioc.factory.AutowireCapableBeanFactory;import us.codecraft.tinyioc.factory.BeanFactory;/*** * @author * @create 2017-05-29 10:59**/public class BeanFactoryTest { @Test public void test(){ //1·初始化beanFactory BeanFactory beanFactory = new AutowireCapableBeanFactory(); //2·注入bean BeanDefinition beanDefinition= new BeanDefinition(); beanDefinition.setBeanClassName("us.codecraft.tinyioc.HelloWorldService"); beanFactory.registerBeanDefinition("helloWorldService",beanDefinition); //3·获取bean HelloWorldService helloWorldService=(HelloWorldService)beanFactory.getBean("helloWorldService"); helloWorldService.printHelloWorld(); }}
整体代码就是这些,下边是执行结果:
第二步的内容就是这些,下边我们来分析一下这个代码实现的过程和上一篇博客的区别点:
上边已经分析过是“初始化”的工作由谁来做?怎么做?
与step1主要不同的地方就是“初始化”的工作由谁来做?
很明显,step1,是在main方法中通过new实例化bean对象再放到beanDefinition对象中管理。step2是怎么做的呢?
step2中想要达到的效果就是:动态加载bean对象,具体详解前先来思考下边的一个问题:
·给你一个字符串变量,它代表一个类的包名和类名,你怎么实例化它?
你首先想到的是不是new实例化?看下边代码:
A a=(A)Class.forName("package.A").newInstance();//拆开来看Class t=Class.forName("package.A");t.newInstance();
这句代码和A a = new A();是一样的效果。既然一样的效果,那区别是什么?换句话说,我应该选择哪种方式呢?
从代码中可以看出,newInstance()实际上是把new方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。
step2的代码中就是通过Class.forName("包名.类名")来动态加载的类,然后在自动加载类AutowireCapableBean中该类的newInstance()创建的bean对象。这样的好处是:我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。
- 《step2:tiny Spring IoC学习二》——将bean创建放入工厂
- 【深入Spring】——Tiny Spring IoC(一)Bean
- 《step3:tiny-Spring-IoC学习三》——为bean注入属性
- 《step4:tiny-spring-ioc学习四》——读取xml配置来初始化bean
- 【深入Spring】——Tiny Spring IoC(二)BeanClass
- 《step5:tiny-spring-ioc学习五》——ApplicationContext登场
- 学习Spring(二) 调用静态工厂方法创建Bean
- Spring学习(三)ioc工厂bean深入理解
- Spring学习(三)ioc工厂bean深入理解
- Spring-工厂创建Bean
- 【深入Spring】——Tiny Spring IoC(三)PropertyValues
- Spring入门学习——调用静态工厂方法创建Bean
- Spring入门学习——调用一个实例工厂方法创建Bean
- 《step1:tiny Spring IoC学习一》——最基本的容器BeanFactory
- Spring IOC-Servlet加载到bean工厂
- 03-Spring-ioc工厂bean深入理解
- Spring学习笔记(二) IoC容器与Bean
- 自己动手写spring(二) 创建一个bean工厂
- 新的开始,Hello World !
- 支持向量机(Support Vector Machine,SVM)详解
- merge和update的区别
- 《我是这样封装Windows7的》。。。。。。
- 如何保证用log4J 写log 的时间和系统设置的timezone 保持一致
- 《step2:tiny Spring IoC学习二》——将bean创建放入工厂
- 隐式Intent的使用 app分享功能的实现
- $.ajax POST
- Windows下关于Nginx自动切割与异地备份
- 做网站优化(SEO)的几个关键点
- maven中properties标签定义变量
- Qt 与 VTK 在实现 3D 效果上的优劣
- ionic 版本更新日志
- gcc 编译选项