通过实例浅谈春运作机制
看到这个标题大家可能又想:哎,又一个重新发明轮子的人。在这里很想先声明一下,写这篇文章只是想让大家了解一下Spring到底是怎么运行的,并不是想重造轮子噢,希望大家看完这篇文章后能对Spring运作机制有更深入的了解,希望这篇文章对你有所帮助喔!好,言归正传,让我们来一起探索吧!
我们先从最常见的例子开始吧
Java的代码
- 公共静态无效的主要(字串[] args){
- ApplicationContext的 背景 = 新 FileSystemXmlApplicationContext来(
- “的applicationContext.xml”);
- 动物 动物 =(动物)context.getBean(“动物”);
- animal.say();
- }
这段代码你一定很熟悉吧,不过还是让我们分析一下它吧,首先是applicationContext.xml
Java的代码
- < bean的 ID = “动物” 类= “phz.springframework.test.Cat” >
- < 属性 名= “姓名” >
- < 值>的小猫</ 值>
- </ 属性>
- </ 豆>
他有一个类phz.springframework.test.Cat =
Java的代码
- 公共类Cat实现动物{
- 私人字符串名称;
- 公共无效的发言权(){
- 的System.out.println(“我”+姓名+“!”);
- }
- 公共无效setname可以(字符串名称){
- this.name =名称;
- }
- }
实现了phz.springframework.test.Animal接口
Java的代码
- 公共接口动物{
- 公共无效说();
- }
很明显上面的代码输出,我的小猫!
那么到底春天是如何做到的呢?
接下来就让我们自己写个春天来看看春天运作机制吧!
首先,我们定义一个Bean的类,这个类用来存放一个豆拥有的属性
Java的代码
- / *豆ID * /
- 私人字符串ID;
- / * Bean类* /
- 私人字符串类型;
- / * Bean属性* /
- 私人地图< 字符串,对象> 属性 = 新 的HashMap < 字符串,对象>();
一个豆包括编号,类型,和属性。
接下来春天 的标识,HasMap
地图配置可以像下面的
Java的代码
- < bean的 ID = “测试” 级= “测试” >
- < 属性 名= “testMap” >
- < 图>
- < 进入 关键= “A” >
- < 值> 1 </ 值>
- </ 入门>
- < 进入 关键= “B” >
- < 值> 2 </ 值>
- </ 入门>
- </ 图>
- </ 属性>
- </ 豆>
春天的运作机制中是怎样保存上面的配置呢,代码如下?
Java的代码
- 如果(beanProperty.element(“映射”)!= NULL){
- 地图< 字符串,对象> propertiesMap = 新 的HashMap < 字符串,对象>();
- 元素 propertiesListMap =(元素)的BeanProperty
- .elements()得到(0)。
- 迭代器<?> propertiesIterator = propertiesListMap
- 。.elements()迭代器();
- 而(propertiesIterator.hasNext()){
- 元素 兽医 =(元)propertiesIterator.next();
- 如果(vet.getName()。等于(“入口”)){
- 字符串 键 = 兽医.attributeValue(“钥匙”);
- 迭代器<?> valuesIterator = 兽医.elements()
- .iterator();
- 而(valuesIterator.hasNext()){
- 元素 值 =(元素)valuesIterator.next();
- 如果(value.getName()。等于(“价值”)){
- propertiesMap.put(键,value.getText());
- }
- 如果(value.getName()。等于(“参考”)){
- propertiesMap.put(键,新的String [] {值
- .attributeValue(“豆”)});
- }
- }
- }
- }
- 。bean.getProperties()摆(姓名,propertiesMap);
- }
接下来就进入最核心部分了,让我们看看春天到底是怎么依赖注入的吧,其实依赖注入的思想也很简单,它是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。让我们看看具体它是怎么做的吧。
首先实例化一个类,像这样
Java的代码
- 公共静态对象的newInstance(弦乐的className){
- 类<?> CLS = 空;
- 对象 的obj = 空;
- 尝试{
- CLS = 类.forName(类名);
- OBJ = CLS .newInstance();
- }赶上(ClassNotFoundException异常E){
- 抛出新的RuntimeException(五);
- }赶上(InstantiationException五){
- 抛出新的RuntimeException(五);
- }赶上(IllegalAccessException五){
- 抛出新的RuntimeException(五);
- }
- 返回的obj;
- }
接着它将这个类的依赖注入进去,像这样
Java的代码
- 公共静态无效的SetProperty(obj对象,字符串名称,字符串值){
- 类<? 扩展 对象> clazz所 = OBJ .getClass();
- 尝试{
- 字符串 方法名 = returnSetMthodName (名称);
- 方法[] 毫秒 = clazz所.getMethods();
- 对于(方法M:毫秒){
- 如果(m.getName()。等于(方法名)){
- 如果(m.getParameterTypes().length == 1){
- 类<?> clazzParameterType = m.getParameterTypes()[0];
- setFieldValue(clazzParameterType.getName(),价值,男,
- OBJ);
- 打破;
- }
- }
- }
- }赶上(SecurityException异常E){
- 抛出新的RuntimeException(五);
- }赶上(抛出:IllegalArgumentException五){
- 抛出新的RuntimeException(五);
- }赶上(IllegalAccessException五){
- 抛出新的RuntimeException(五);
- }赶上(的InvocationTargetException五){
- 抛出新的RuntimeException(五);
- }
- }
最后它将这个类的实例返回给我们,我们就可以用了。我们还是以Map为例看看它是怎么做的,我写的代码里面是创建一个HashMap并把该HashMap注入到需要注入的类中,像这样,
Java的代码
- 如果(值的instanceof地图){
- 迭代器<?> entryIterator =((地图<? , ?>)值).entrySet()
- .iterator();
- 地图< 字符串,对象> 图 = 新 的HashMap < 字符串,对象>();
- 而(entryIterator.hasNext()){
- 进入<? , ?> entryMap =(进入<? , ?>)entryIterator.next();
- 如果(entryMap.getValue()的instanceof的String []){
- map.put((弦乐)entryMap.getKey()
- 的getBean(((字符串[])entryMap.getValue())[0]));
- }
- }
- BeanProcesser.setProperty(OBJ,财产,地图);
- }
好了,这样我们就可以用春给我们创建的类了,是不是也不是很难啊?当然Spring能做到的远不止这些,这个示例程序仅仅提供了Spring最核心的依赖注入功能中的一部分。这也是Spring运作机制中的一部分。
本文参考了大量文章无法一一感谢,在这一起感谢,如果侵犯了你的版权深表歉意,很希望对大家有帮助!
附件中包含该山寨Spring的源码,核心只有五个类,还有一个测试程序,phz.springframework.test.AnimalSayApp,可以直接运行。