本文是自己的学习过程,仅用于自己知识点的总结,并没有高深的,巧妙的技术在里面,大佬请绕行
1.什么是spring
- 什么是框架:大师写好的半成品
- spring:不是某层的功能性框架;用于整合项目的项目
- spring是一个开源的Java开发框架,它提供了一种全面的解决方案,用于构建企业级应用程序。Spring框架的设计理念是基于面向对象的编程思想和松耦合的架构原则,旨在简化Java应用程序的开发,并提供可扩展性和灵活性。
2.ioc的概念
- IOC:Inversion of Control 控制反转
把对象的创建、分配、销毁等所有工作不再有程序来实现 而是交给sping容器来管理 - DI : Dependency Injection 依赖注入
在运行时 通过反射动态的把项目需要的对象 注入到程序中
- 依赖注入是实现控制反转的一种设计方法,并不是说依赖注入等于控制反转(Inversion of Control,IoC)。控制反转是思想,依赖注入是具体实现方式
什么是控制反转
- 控制: 创建对象,对象的属性赋值,对象之间的关系管理。
- 反转: 把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。 由容器代替开发人员管理对象。创建对象,给属性赋值。
3.ioc的优点
ioc的思想最核心的地方在于,资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。
灵活性
为广泛使用的接口更改实现类更简单(例如,用生产实例替换模拟web服务)
更改给定类的检索策略更简单(例如,将服务从类路径移动到JNDI树)
添加拦截器很简单,只需在一个地方完成(例如,向基于JDBC的DAO添加缓存拦截器)
可读性
该项目有一个统一一致的组件模型,没有工厂(如DAO工厂)
如果没有依赖项查找代码(例如对JNDI InitialContext的调用),代码更简洁,也不会杂乱无章
可测试性
当依赖项通过构造函数或setter公开时,它们很容易替换mock
更容易的测试导致更多的测试
更多的测试会带来更好的代码质量、更低的耦合性和更高的内聚性
4.ioc的使用
4.1导入jar包
-
创建java项目
-
导入jar
com.springsource.org.apache.commons.logging-1.1.1.jar:日志系统 com.springsource.org.apache.log4j-1.2.15.jar::::::日志系统 org.springframework.asm-3.0.1.RELEASE-A.jar::::::字节码操作依赖的jar org.springframework.beans-3.0.1.RELEASE-A.jar:::::javavbean操作的jar org.springframework.context-3.0.1.RELEASE-A.jar::::spring辅助功能的jar:::验证/邮件 org.springframework.core-3.0.1.RELEASE-A.jar::::::spring核心 org.springframework.expression-3.0.1.RELEASE-A.jar:::spring表达式依赖的jar
4.2创建配置文件
-
配置文件名可以随意—— 唯一可以随意填写的内容
<?xml version="1.0" encoding="UTF-8"?> <!-- 引入dtd文件、scheam文件 为xml文件定义语法规则 --> <!-- dtd::document type defined:::文档类型定义文件:::给xml文件定义规则:::标签、属性、嵌套关系 --> <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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> </beans>
4.3定义实体类
1 实现序列化接口:Serializable 2 属性私有化封装:private+getset方法 3 属性包装类类型 4 无参数的构造方法
4.4在配置文件中创建对象
-
通过bean标签
-
赋值
赋值方式1:property标签
调用无参数的构造方法创建对象,通过set方法给属性赋值
赋值方式2:constructor-arg标签
调用对用的有参方法创建对象,标签数量必须和构造方法一致,即必须有对应的构造方法。顺序可以不和构造方法的一致
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> 方式1: <bean class="springDemo.Teacher" id="t1"> <!-- 相对于src--> <property name="tid" value="1001"/> <property name="tname" value="张三"/> <property name="tsex" value="女"/> <property name="tdy" value="false"/> <property name="tsalary" value="1569.15"/> </bean> 方式2: <!-- this.tid = tid;--> <!-- this.tname = tname;--> <!-- this.tsex = tsex;--> <!-- this.tsalary = tsalary;--> <!-- this.tdy = tdy;--> <bean class="springDemo.Teacher" id="t2"> <!-- 创建一个 springDemo.Teacher类型的对象:::--> <constructor-arg name="tsalary" value="3569.15"/> <constructor-arg name="tdy" value="false"/> <constructor-arg name="tid" value="1002"/> <constructor-arg name="tname" value="李四"/> <constructor-arg name="tsex" value="男"/> </bean> </beans>
4.5启动类
-
获取上下文对象的方式
方式1:ClassPathXmlApplicationContext 类
方式2:FileSystemXmlApplicationContext
package springDemo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class TestDemo {
public static void main(String[] args) {
// 1 获取上下文对象:::指定xml文件的位置::路径相对于src
//ClassPathXmlApplicationContext相当于src
ClassPathXmlApplicationContext context;
context = new ClassPathXmlApplicationContext("springDemo/spring_ioc_01.xml");
Teacher t1 = (Teacher) context.getBean("t1");//2 通过getBean方法获取标签创建的对象
System.out.println(t1);
context.close();//3 关闭
//1 获取上下文对象:::指定xml文件的位置::路径相对于当前项目
FileSystemXmlApplicationContext context1 =
new FileSystemXmlApplicationContext("src/springDemo/spring_ioc_01.xml");
//2 通过getBean方法获取标签创建的对象
Teacher t2 = (Teacher) context1.getBean("t2");
System.out.println(t2);
context1.close();//3 关闭
}
}
4.6对象关联
-
通过 ref 属性来指定对应关联的bean
-
如果关联的been 在其他配置文件中,在当前配置文件中通过import标签 导入需要的配置文件
-
如果不导入,将会报错:无法解析 Bean 't1'
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 给单值数据类型的属性赋值::value -->
<!-- 给引用数据类型的属性赋值::ref -->
<bean class="springDemo.Student" id="s1"> <!-- 相对于src-->
<property name="sid" value="1001"/>
<property name="sname" value="张三"/>
<property name="sex" value="女"/>
<property name="sage" value="18"/>
<property name="score" value="85.2"/>
<property name="teacher" ref="t1"/><!--对象关联,需要导入需要的配置文件,如果不导入,将会报错:无法解析 Bean 't1'-->
</bean>
<import resource="spring_ioc_01.xml"/><!--导入需要的Teacher t1的配置文件-->
</beans>
4.7集合数组类型的属性
-
格式
<!-- 数据为单值数据类型 -->
<property name=" 属性名字 ">
<属性的类型 value-type="属性需要的数据类型">
<value>值</value>
<value>值</value>
<value>值</value>
<value>值</value>
</属性的类型>
</property>
<!-- 如果值得类型是其他配置文件对象 则是对象关联-->
<property name="属性名字">
<属性的类型 value-type="test01.Student 属性需要的数据类型 ">
<ref bean="值"/>
<ref bean="值"/>
<ref bean="值"/>
</属性的类型>
</property>
<!-- 给map类型属性赋值:private Map<String, Integer> mapStrInt; -->
<property name="mapStrInt">
<map key-type="java.lang.String" value-type="java.lang.Integer">
<entry key="k_1" value="111" />
<entry key="k_2" value="112" />
<entry key="k_3" value="113" />
<entry key="k_4" value="114" />
</map>
</property>
-
示例
<bean class="test01.Teacher" id="t1">
<property name="tid" value="1"/>
<property name="tname" value="高老师"/>
<property name="tsalary" value="3500"/>
<!-- 给基本类型数组赋值 private int[] arrInt;-->
<property name="arrInt">
<array value-type="int">
<value>1001</value>
<value>1002</value>
<value>1003</value>
</array>
</property>
<!-- 给引用类型数组赋值private Student[] arrStu; -->
<property name="arrStu">
<array value-type="test01.Student">
<ref bean="s1"/>
<ref bean="s2"/>
<ref bean="s3"/>
</array>
</property>
<!-- 给单值数据类型list赋值:private List<Integer> listInt; -->
<property name="listInt">
<list value-type="java.lang.Integer">
<value>1001</value>
<value>1003</value>
<value>1005</value>
<value>1007</value>
</list>
</property>
<!-- 给引用数据类型list赋值:private List<Student> listStu; -->
<property name="listStu">
<list value-type="test01.Student">
<ref bean="s1"/>
<ref bean="s2"/>
<ref bean="s3"/>
</list>
</property>
<!-- 给set类型属性赋值:private Set<Integer> setInt; -->
<property name="setInt">
<set value-type="java.lang.Integer">
<value>11011</value>
<value>12011</value>
<value>13011</value>
<value>14011</value>
</set>
</property>
<!-- 给map类型属性赋值:private Map<String, Integer> mapStrInt; -->
<property name="mapStrInt">
<map key-type="java.lang.String" value-type="java.lang.Integer">
<entry key="k_11" value="111" />
<entry key="k_12" value="112" />
<entry key="k_13" value="113" />
<entry key="k_14" value="114" />
</map>
</property>
4.8 bean的生命周期
- 创建对象:默认情况下上下文对象加载核心品种文件时 就创建所有的bean标签定义的对象
- 对象初始化:对象一旦创建 就立刻调用bean的init-method对应的方法 进行对象的初始化
- 调用对象:getBean方法执行时 获取此唯一对象
- 销毁对象:上下文对象调用close方法前:会调用bean的destroy-method 来销毁对象
4.9 懒加载
-
懒记载只针对于:scope=singleton单例
-
默认情况下:是立即加载:::核心配置文件一记载 bean就立刻创建对象
-
通过设置bean的lazy-init="true" 来指定在调用getBean方法时才创建对象
<?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/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="springDemo.Teacher" id="t1" init-method="init" destroy-method="destroy" lazy-init="true"> <!-- 相对于src--> <property name="tid" value="1001"/> <property name="tname" value="张三"/> <property name="tsex" value="女"/> <property name="tdy" value="false"/> <property name="tsalary" value="1569.15"/> </bean> </beans>
5. ioc的缺点
- 创建对象的步骤变复杂了,不直观,对小白来说的更难。
- 因为使用反射来创建对象,所以在效率上会有些损耗。但相对于程序的灵活性和可维护性来说,这点损耗是微不足道的。
-
缺少IDE重构的支持,如果修改了类名,还需到XML文件中手动修改,这似乎是所有XML方式的缺憾所在。