1. 概述
本篇文章主要是简单的介绍一下Spring是什么,有什么作用,以及简单的使用方法。
这里给大家提供 官方参考文档 当然,还有中文的学习路线图: W3cshcool 或者 这里
学习在于坚持,Spring 是整个Spring全家桶的基石,如果想继续学习其他Spring团队开发的框架,就一定要先打好Spring的基础
2. Spring 中的Ioc 和 DI
Ioc 是 Inverse of control 的缩写,中文译为 控制反转,好多的地方的解释就是:“我想要的东西由别人创建给我”。我认为这句话很不好理解,所以我总结了一下:
在我们正常情况下的编程中,当我们需要一个对象,或者类中有引用变量属性需要指向一个实际的对象的时候,我们需要自己来new并且控制对象引用。而Spring会将
我们需要的所有对象统一管理起来,我们需要什么就直接去Spring中的容器中取就可以了。这样,所有的对象就不需要我们自己new了,而是交给Spring替我们new和管理。
换句话说,所有的对象创建和依赖都不再需要我们来控制,而是交给其他的东西去控制(Spring),这就是控制反转。
DI 其实可以说是Ioc中的一小部分的实现方式。 上面已经说过,我们所有的对象都不再需要自己去new或者控制,引用变量属性指向实际变量的时候,也是由Spring替我们完成,
而这个引用变量属性指向其他对象的控制就是依赖注入——换句话说,就是一个类中需要使用另外一个对象,那么这个对象会由Spring为我们自动注入进来,称作依赖注入。
那这样做有什么好处呢? 很简单,我们再也不用管理复杂的依赖关系了,甚至连创建对象都不需要。这样会大大减轻我们开发的负担。
3.Spring 中的AOP
AOP 是 Aspect Oriented Programming 的缩写,中文译为 面向切面编程。这是一种编程思想。 它的侧重点是一个方面(切面)。我们传统的面向对象(OOP)方式关注的是一个个的对象,抽象的是
一个一个的包含属性和行为的类;而瞄向切面(AOP)关注的是一个切面,例如无论是controller层、service层还是dao层,都需要进行日志的记录,那么就可以使用AOP面向日志切面进行统一编程。
AOP的实现方式有很多种,例如使用动态代理,在运行时不改变源代码而增加一些必要的功能等。
4.Spring 的使用 配置元数据(bean)
配置元素据,其实就是将我们需要的对象实例(bean)和实例的依赖关系告诉给Spring,我们这里先使用XML文件进行配置,后面还可以进行基于注解的配置,甚至可以使用基于JAVA的配置。
首先,我们先来导入一下约束(这个可以使我们编辑的xml文件符合spring要求的语法规范)
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 这里是我们需要声明的bean 所有的bean 必须在beans标签内 --> </beans>
然后声明一个bean的语法是这样的: 这里面的id是这个实体在spring容器中的名字,class 是这个类的完整类名(注意是完整类名)
我们可以看到,不仅可以用id给一个bean起名字,还可以使用name给一个bean起名字。两者的区别是: id只能指定一个名称,切不能有特殊字符,name可以指定多个名称(逗号分割),而且可以有一些特殊字符。
<bean id="xxx" class="xxx"/>
<bean name="xxx" class="xxxxxx"/>
这只是简单的声明一个bean,那么如果我们一个bean里面有一个属性需要依赖另一个bean怎么办 ? 这里就使用到了依赖注入! 依赖注入有两种常见的方法:
1.构造器注入(不推荐使用这种方法,因为不是每一个bean都一定有有参的构造方法)
简单地说就是在bean 中添加属性 constructor-arg 属性来反射该构造方法,然后设值(若不存在该构造方法则会抛出异常)
constructor-arg 可以直接使用 value 属性 给bean中的属性赋值 也可以使用 ref 属性给bean中的属性注入其他对象
<bean name="名称" class="完整类名"> 这里是构造一个bean <constructor-arg name="参数名" value="值"/> 构造方法通过参数名直接设值 <constructor-arg name="参数名" ref="其他bean"/> 构造方法注入其他已经存在的bean (依赖注入) </bean>
2.setter方法注入(推荐这种方式,因为任何一个类都一定有构造方法(虽然说可能被私有化,但也是有),通过构造方法先创建对象,然后再调用setter方法进行依赖注入,比较常用)
<bean name="名称" class="完整类名"> 构造一个bean <property name="属性名" value="属性值"/> 构造完毕后 通过属性名直接设值值 <property name="属性名" ref="其他bean"/> 构造完毕后 通过属性名注入其他已经存在的bean (依赖注入) </bean>
Spring中基本所有的bean 都可以使用这种 xml方式配置,下面给出 bean标签的全部属性:
1. class 属性 : 用来指定该bean的完整类名,即该类是哪个类的bean
2. id / name : 用来指定该bean 在容器中的名称(id只能指定一个,而且不能有特殊符号;name可以指定多个名称,可以有简单的特殊符号)
3. scope : 用来指定该bean的作用范围:
1.singleton:(默认) 单例模式,在IOC容器中只存在一个。
2.prototype : 多例模式,即在IOC中可以同时存在多个(每次注入时都可能是容器新生产的)
3.request / session /application 在servlet中用到,声明周期分别与 request / session / application 相同
4. constructor-arg : 指定构造方法参数 用于依赖注入时的构造方法注入方式,有几个属性:
4.1 value : 该属性的值(字面量表示)
4.2 ref : 该属性使用IOC容器中已经存在的对象注入 ref的值就是IOC容器中存在的对象的名称
4.3 type: 指定构造方法参数的类型 (基本类型值为基本类型名称 如:“int” ;引用类型值为全类名 如:“java.lang.String”)
4.4 index : 构造方法中的参数下标(第几个参数),注意 这个下标是 base-0 的 (从0开始)
4.5 name: 构造方法中参数的名称。
5. property:用来指定bean的属性的值,用于setter方法注入,有几个属性:
5.1 value:该属性的值(字面量表示)
5.2 ref : 该属性使用IOC容器中已经存在的对象注入 ref的值就是IOC容器中存在的对象的名称
5.3 name :需要被依赖注入的属性的名称
props、list、set和map 的注入: 使用现有的标签进行注入:
<bean id="moreComplexObject" class="example.ComplexObject"> <!-- results in a setAdminEmails(java.util.Properties) call --> <property name="adminEmails"> <props> <prop key="administrator">administrator@example.org</prop> <prop key="support">support@example.org</prop> <prop key="development">development@example.org</prop> </props> </property> <!-- results in a setSomeList(java.util.List) call --> <property name="someList"> <list> <value>a list element followed by a reference</value> <ref bean="myDataSource" /> </list> </property> <!-- results in a setSomeMap(java.util.Map) call --> <property name="someMap"> <map> <entry key="an entry" value="just some string"/> <entry key ="a ref" value-ref="myDataSource"/> </map> </property> <!-- results in a setSomeSet(java.util.Set) call --> <property name="someSet"> <set> <value>just some string</value> <ref bean="myDataSource" /> </set> </property> </bean>
当然,还有一些其他不常用属性 如:自动注入模式等 这里就不再赘述。
5.Spring 使用
我们使用Spring的前提是我们已经有这些需要被管理的类并且配置好了所有的bean,即我们有配置好bean的xml文件,这里我们将这个文件取名为applicationContext.xml 并将其放在类路径下(注意,路径和文件名是有影响的,后面的文章会再分析)
上面准备好了以后,我们再来认识一个新的类——ApplicationContext 他是BeanFactory 的子接口,提供了很多高级特性,几乎所有场合都是直接使用ApplicationContext。
我们来简单使用ApplicationContext的一个实现类 ClassPathXmlApplicationContext 来从类路径下加载bean的配置文件,然后启动IOC容器。(ApplicationContext有很多实现类:FileSystemApplicationContext——文件系统加载bean配置
并启动IOC容器、ConfigurableApplicationContext 带有刷新和关闭的IOC容器启动器等)
ApplicationContext context = new ClassPathXmlApplicationContext("xml配置文件名称");
这样我们会得到一个 ApplicationContext 对象 context 我们可以看做这个对象为启动后的IOC容器,可以从其中取出我们配置好的Bean
示例代码: 请到GitHub下载