1.什么是框架(Framwork)
这是第一个要了解的事,对于没有框架编程基础的人,首先对此的概念并不清晰.在此给出一个大体定义:
框架就是对编程中特定问题的封装和抽取.属于是一种为了降低编程难度,提高性能,提高系统的可维护性,可扩展性的半成品.
框架的中一般对软件中的特性和共性进行了抽取,封装.主要还是用来降低编程难度的(犯懒的:这是我的一位老师"教育"我的,好东西都是懒人发明的)
举个简单的例子就像简历的模板,不过我感觉还是用鼠标宏脚本比喻更恰当,重复性的操作就做成可复制性的.
2.框架的设计
这个问题我感觉还是把框架学完才能有个完整的理解,在此先罗列出来.
框架设计一般从三个维度来考虑:
(1)面向对象:从静态角度,有哪些对象,属性,行为,对象间关系,利用对象解决问题.
(2)面向切面:动态角度,对象运行中如何为对象扩展新的业务功能.
(3)面向服务(SOA):从服务业务的角度进行细粒度控制,进行RPC(跨进程)调用,如微服务.
讨论过之前的两个问题之后进入今天的正题
Spring
1.Spring概述
spring是一个框架(Framwork),主要从三个维度(面向对象,面向切面,面向服务)通过整合一定的
资源解决软件中一些相关问题.
注意:他没有做到很多的功能但是他可以整合各种资源,就像多口的插板.
spring主要解决了对象的创建与对象的管理问题,其中对象的创建是通过工厂创建,管理对象上重点是管理对象间的依赖关系
简单罗列Spring解决的问题:
1.对象的创建(通过工厂创建)
2.对象的管理(重点管理依赖关系)
下面我们就看看Spring怎样去创建对象的
我们知道按照平时创建对象的方式主要有直接创建还有通过一些静态工厂,也就是静态的法
直接创建: Date date = new Date(); 静态工厂: Date date2 = DateUtils.getInstance();
除了以上两种方式,再一种就是我们要讲的Spring的动态工厂方式创建
首先我们创建一个xml配置文件
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.3.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 上面的东西不用关心,都是一些约束文件
我们主要看其中的bean标签-->
<bean id="date1" class="java.util.Date"/>
<bean id="map1" class="java.util.HashMap"/>
<bean id="hello" class="beans.Hello"/>
</beans>
然后我们在测试代码中这样编写
main{ //初始化Spring容器对象 ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); System.out.println(ctx); //2.获取需要的对象(此对象由容器(工厂)创建) //第一种方式 Date date1 = (Date)ctx.getBean("date1"); System.out.println(date1); //第二种方式(不用强转) Date date2=ctx.getBean("date1",Date.class); System.out.println(date2); //3.释放资源 ctx.close(); }
我们定义了<bean id="date1" class="java.util.Date"/>这样的标签.然后初始化一个Spring的容器对像(ClassPathXmlApplicationContext),初始化过程中Spring读取了定义的配置文件,并创建了一个对应的Date对象放到了容器中.在我们需要使用时就是用getBean方法获取到.(注意最后不用时别忘了关闭容器)
这就是Spring帮我们管理对象的最简单的例子,这种方式我们称为控制反转(IOC),它是Spring的核心机制,之后我们展开来说IOC
Spring IOC
Spring IOC概述
1.1 IOC概述
IOC(Inversion of Control)意为控制反转,是Spring框架中管理对象的机制,控制反转是啥,看上面的例子也能大概理解,就是将对象的控制权转给了Spring,这样能有效的实现对象的解耦,提高可维护可扩展性.
IOC是Spring框架的基础和核心,IOC借助DI(依赖注入)来实现的.(至于依赖注入我放到下一节去说,先大体解释一下-----我们创建对象不能单单像这样使用无参构造new对象吧,总会有传递参数初始化对象属性的时候,这种时候我们就用到了依赖注入)
1.2 Spring Bean容器
Bean容器负责创建Bean对象,并管理bean对象
底层根据元数据的描述与反射进行对象的创建!!! (理解这一点很重要,我们放到扩展内容中去讲)
用直白的话讲:Spring创建的个桶子(Bean容器),把从配置文件中读到对象创建出来装到这个桶子里,方便我们直接取用.
说到现在可能有些人有疑问,这样做岂不是更麻烦,又要写配置文件又要创建容器,还不如直接new.但是我们从学习编程就被前辈们教诲"优秀的代码是低耦合的",使用Spring的IOC就是充分的实行解耦的思想.当我们的项目越来越大,一旦要去修改其中的对象,还需要修改代码.然而使用配置的方式,我们只要修改配置信息就好,这样我们甚至可以实现对象的热插拔(就像USB).
今天的基本内容已经讲完,以下是扩展内容
=============================================================
了解了IOC的根本意义与基础使用,下面我们来说说他是如何实现的那?
来自己实现以下,首先说明Bean容器用元数据加反射最后存到map中实现的
一般容器对象都用到了map结构
写一个简单的xml文件
<beans>
<bean id="date1" class="java.util.Date"/>
<bean id="map1" class="java.util.HashMap"/>
</beans>
然后是实现动态工厂
/** * 根据配置文件创建对象,并将对象存储到map */ public class ApplicationContext { private static Map<String,Object> beanMap = new HashMap<>(); public ApplicationContext(String file){ init(file); } private void init(String file){ //1.读取文件(从类路径获取:1.获取当前类的对象2.获取类的加载器3.获取类路径) //这里用到了类加载器来读取文件 InputStream in = getClass().getClassLoader().getResourceAsStream(file); //2.解析文件(dom4j) SAXReader reader = new SAXReader(); Document doc = null; try { doc = reader.read(in); } catch (DocumentException e) { e.printStackTrace(); throw new RuntimeException(e); } Element root = doc.getRootElement(); List<Element> list = root.elements("bean"); for (Element ele : list) { String idValue = ele.attributeValue("id"); String clsValue = ele.attributeValue("class"); //System.out.println(idValue); //System.out.println(clsValue); //3.利用反射创建对象 Object obj = null; try { //注意一forName先是获得的Class对象 Class cls = Class.forName(clsValue); obj = cls.newInstance(); } catch (Exception e1) { e1.printStackTrace(); throw new RuntimeException(e1); } //4.存储对象 beanMap.put(idValue, obj); } } /**从map中获取对象*/ public Object getBean(String key){ return beanMap.get(key); } // 泛型(解决不用强转) public <T> T getBean(String key,Class<T> cls){ return (T)beanMap.get(key); } public void close(){ beanMap.clear(); beanMap=null; } }
调用
main{ ApplicationContext ctx = new ApplicationContext("beans.xml"); Date date3 = (Date)ctx.getBean("date1"); System.out.println(date3); //**不用强转 Date date4 = ctx.getBean("date", Date.class); ctx.close(); }
完
第一次编写博客,对于Spring也是第一次学习,理解不深,有错误请在评论区轻喷