Spring
为什么引入Spring框架
为了提高开发效率和实现模块之间的高聚合低耦合,所以引入了Spring框架
高聚合低耦合
高内聚
内聚是指模块内的联系,各个元素之间紧密联系共同完成任务,模块内的联系越紧密越好,这样可以提高他们之间配合的工作效率 ——(模块之内各个元素男女搭配干活不累)
低耦合
耦合是指各个模块之间的联系,或者是说依赖关系,我们期望的效果应该是他们之间的依赖关系越弱越好,这样不会因为个别模块的失常导致全盘皆输——(各个模块能够独立,离开其他模块也能发光)
Spring的核心IOC和AOP
IOC(反转控制或控制反转)
IOC是什么
对于模块之间的联系/依赖,我们想要实现降低他们之间的联系/依赖,这个实现的行为就称为解耦,解耦即降低耦合度
IOC就做了各个模块之间解耦的操作,通过spring
IOC做了什么
工厂模式
在实际开发中我们可以把工厂模式中三层互相依赖的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来,在接下来的使用的时候,直接拿过来用就好了
工厂就是读取配置文件,创建对象然后把对象存到一个spring容器内,然后提供获取对象功能的类——是一个类
AOP(面向切面编程)
使用Spring
在pom.xml中添加依赖
<dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.1.0.RELEASE</version></dependency>
我们需要的实际是
Spring的四个依赖,但是只需要导入spring-context就可以在扩展出来的引用依赖中,互相引用
在resourses下创建xml配置文件
配置文件的位置和文件的头如上图所示
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
这个配置文件用来管理配置的类
在测试方法内创建对象
//获取到spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");//读取xml配置文件,创建对象User userimpl = applicationContext.getBean("userimpl", User.class);//对象调用其方法 userimpl.count();
读取xml文件创建对象的getBean参数
//获取到spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");User userimpl = applicationContext.getBean("userimpl"); //传入bean ID 获取User userimpl = applicationContext.getBean( User.class);//传入User类型 获取User userimpl = applicationContext.getBean("userimpl", User.class);//都传
Bean标签的使用
Bean标签的属性
属性名 | 值 |
---|---|
id | 自定义命名管理类的唯一标识,用来创建对象时引用 |
class | 管理类的全限定类名 |
scope | 管理类对象的作用范围,默认singleton(单例),prototype(多实例), |
init-method | 初始化对象的名称 |
destory-method | 销毁对象的方法名称 |
Bean标签属性的补充
init-method
默认创建对象时调用无参构造,如果类中没有无参构造直接通过spring读取xml配置文件创建对象会报错,在xml文件中在类对应的bean标签内提供
<constructor-arg>
标签,对有参构造做一定的描述,然后spring读取xml配置文件创建对象时就会自动调用配置好的有参构造
<bean id="userimpl" class="com.kaifamiao.dao.impl.Userimpl“><constructor-arg name="a" value="12345"/>
</bean>
scope
默认为singleton(单例),此时创建的对象为唯一的,全局只有这个对象的一个实例,spring容器启动时被创建,容器销毁对象即回收
prototype(多实例),创建的对象是不同的对象,访问对象时才会创建
就导致
singleton修饰的类,在创建spring容器时就调用无参构造或者有参构造并创建对象
prototype修饰的类,在工厂创建实例的时候才会调用无参构造或者有参构造并创建对象
实例化Bean的三种方式
1.使用构造函数(默认为无参构造)
使用无参构造
<bean id="userimpl" class="com.kaifamiao.dao.impl.Userimpl" scope="prototype"></bean>
使用有参构造
<bean id="userimpl" class="com.kaifamiao.dao.impl.Userimpl“><constructor-arg name="a" value="12345"/> //对有参构造方法做了描述
</bean>
<constructor-arg>
属性的值
找有参构造的参数 | 传参 |
---|---|
name 参数名 (int abc) name = abc | value 参数值(基本数据类型和字符串) |
type 参数类型 (int abc) type = int | ref 参数值(引用数据类型) |
index 参数下标 (int a ,string b) 传入string的index = 1 |
2.使用静态工厂(static)
使用静态/动态工厂首先需要创建工厂类
工厂类内提供创建对象的方法,方法内部可以添加想要实现的功能
创建好之后在xml配置文件中添加管理
<bean id="userimpl" class="com.kaifamiao.factory.StaticFactory" factory-method="getUser">
</bean>
class全限定类名更改为静态工厂的类名,并且添加factory-method
属性,值为工厂内方法名
3.使用动态工厂
同静态工厂创建工厂类并提供创建对象的方法,只不过动态工厂需要提供非静态的方法
创建好之后在xml配置文件中添加管理
动态工厂创建对象需要先创建动态工厂类的bean对象,再通过bean对象进行对象的创建
<bean id="InstanceFactory" class="com.kaifamiao.factory.InstanceFactory"/>
<bean id="userimpl" factory-bean="InstanceFactory" factory-method="getUserBy">
</bean>
注入依赖
什么是注入依赖
在程序编写时,模块之间的依赖要尽可能的小,我们想要的是低耦合,而IOC做的解耦操作就降低了模块之间的耦合度,但是这个依赖关系并没有完全消失,而是把这种依赖关系交给spring容器来操控,由spring把对象传入所需模块的这个操作,就是注入依赖
注入依赖的三种方式
首先在所要注入依赖的类中添加成员变量定义,以便下边引用
1.构造函数注入
在所要注入依赖的类中提供有参构造,把传入参数值赋值给成员变量,实际做了和setter一样的赋值功能
通过bean标签先创建类对象,然后在bean标签下的<constructor-arg>
标签为类提供的有参构造赋值
找有参构造的参数 | 传参 |
---|---|
name 参数名 (int abc) name = abc | value 参数值(基本数据类型和字符串) |
type 参数类型 (int abc) type = int | ref 参数值(引用数据类型) |
index 参数下标 (int a ,string b) 传入string的index = 1 |
如果参数为引用类型,传参时候用ref传入参数,这个参数为所传入引用类型的bean对象id名
//创建userimpl类的bean对象,供service类传入参数使用
<bean id="userimpl" class="com.kaifamiao.dao.impl.Userimpl">
</bean>
<bean id="serviceimpl" class="com.kaifamiao.service.impl.ServiceImpl"><constructor-arg name="a" value="12345"/><constructor-arg name="b" value="张曼玉"/><constructor-arg name="user" ref="userimpl"/> //这里就用到了上面创建的userimpl的bean对象
</bean>
2.setter方法注入
setter方法注入依赖首先要在类中提供setter方法,用于赋值
然后通过bean标签先创建类对象,然后在bean标签下的<property>
标签为类提供的有参构造赋值
<bean id="userimpl" class="com.kaifamiao.dao.impl.Userimpl">
</bean>
<bean id="serviceimpl" class="com.kaifamiao.service.impl.ServiceImpl"><property name="a" value="12345"/><property name="b" value="张曼玉"/><property name="user" ref="userimpl"/>
</bean>
这里发现setter方法注入和构造方法注入的xml配置文件写法大致相同,不同的是传入参数用的标签是<property>
标签,并且该标签传入参数只有name一个值
3.p名称空间注入(本质上是setter方法注入)
先在类中提供setter方法
在xml配置文件的头导入p名称命名空间
然后在类的bean标签内部添加赋值语句
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"//导入语句为下xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="userimpl" class="com.kaifamiao.dao.impl.Userimpl"></bean><bean id="serviceimpl" class="com.kaifamiao.service.impl.ServiceImpl"//注意p命名空间注入传入参数是在bean内部 基本数据类型和字符串直接用name赋值,引用数据类型用name-ref来赋值p:a="1233456" p:b="武汉" p:user-ref="userimpl"></bean></beans>
补充,注入数组集合元素的方式(本质上是setter方法注入)
首先在类中提供成员
然后在xml配置文件下对该类的bean对象做描述
针对不同的数据类型使用不同的标签进行赋值
以service类中的成员顺序赋值方式为下
<bean id="service" class="com.kaifamiao.service.impl.ServiceImpl">
<!-- <property name="str" value="张三,李四,王五" />-->//对于数组,可以直接拿value传参,也可以像list集合一样传参<property name="str"><list><value>张曼玉</value><value>林青霞</value><value>郭德纲</value><value>周杰伦</value></list></property>//list集合用list标签<property name="list"><list><value>加菲猫</value><value>灰太狼</value><value>美羊羊</value><value>皮卡丘</value></list></property>//set集合用set标签<property name="set"><set><value>阿凡达</value><value>迪士尼</value><value>漫威</value></set></property>//map集合用map标签和entry标签 entry指键值对<property name="map"><map><entry key="喜羊羊" value="123"></entry><entry key="兔八哥" value="456"></entry></map></property>//properties配置用props和prop标签,value写在外边<property name="properties"><props><prop key="name">com.kaifamiao.name</prop><prop key="pace">com.kaifamiao.pace</prop></props></property></bean>
</beans>