Spring
发展
- 2002年 Road Johnon 发表
- 2003年 spring Aop Ioc(控制反转)【DI 依赖注入】
- 现如今:springmvc 、spring data 、springcloud、springboot 等等Spring家族
初始化Spring
- 搭建环境
-
开发Spring至少需要的jar包
- spring-core <spring的核心jar>
- spring-beans <spring的beans>
- spring-aop
- spring-expression
- spring-context
- common-logging(第三方日志)
-
配置 applicationContext.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/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
IoC(控制反转) 与 DI(依赖注入)
-
IoC(inversion of Control,控制反转)
- 为了获取 对象 一般方法为 new object();但是这种方法的弊端是,每次需要创建一个对象即需创建对象。这种方法过于繁琐(为了解耦合),于是引入了简单工厂,每次获取前只需getObject();
- 于是可将IoC简单一个为超级工厂 ,每次获取对象只需先将对象放入Spring容器中,然后直接通过getObject(),获取即可。
-
DI(dependency injection,依赖注入)
- 尽管通过以上的解释我们已经大致理解了什么是IoC,但是理解起来仍有些疑惑,于是IoC的另一种解释即为DI(依赖注入)。
- 将属性值注入给属性,再将属性注入给bean,再将bean注入Spring 容器。获取对象时通过getObject()获取即可;
-
总结:IoC与DI本质相同,仅仅叫法不同,因为IoC描述起来比较模糊,所以才有了DI这一理解方式
依赖注入的三种方式
-
依赖注入使用的底层原理是(反射)【反射是框架的灵魂,理解反射对学习框架事半功倍】
-
为方便理解现有两个类 Stuent 和 Course
- Sudent
package cn.spring.bean; public class Student { private int stuNo; private String stuName; private int age; public Student() { } public Student(int stuNo, String stuName, int age) { this.stuNo = stuNo; this.stuName = stuName; this.age = age; } public int getStuNo() { return stuNo; } public void setStuNo(int stuNo) { this.stuNo = stuNo; } public String getStuName() { return stuName; } public void setStuName(String stuName) { this.stuName = stuName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student{" + "stuNo=" + stuNo + ", stuName='" + stuName + '\'' + ", age=" + age + '}'; } }
- Course
package cn.spring.bean; public class Course { private String curName; private int curScore; private Student student; public Course() { } public Course(String curName, int curScore, Student student) { this.curName = curName; this.curScore = curScore; this.student = student; } public String getCurName() { return curName; } public void setCurName(String curName) { this.curName = curName; } public int getCurScore() { return curScore; } public void setCurScore(int curScore) { this.curScore = curScore; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } @Override public String toString() { return "Course{" + "curName='" + curName + '\'' + ", curScore=" + curScore + ", student=" + student + '}'; } }
- 测试单元
package cn.spring.domain; import cn.spring.bean.Course; import cn.spring.bean.Student; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");//获取Ioc容器 Student student = (Student) context.getBean("student");//获取Student System.out.println(student); Course course = (Course) context.getBean("course");//获取Course System.out.println(course); } }
-
通过 setXXX() 方式
- 在applicationContext.xml 中配置 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="cn.spring.bean.Student"> <property name="age" value="23"/> <property name="stuName" value="张三"/> <property name="stuNo" value="1"/> </bean> <bean id="course" class="cn.spring.bean.Course"> <property name="curName" value="Spring"/> <property name="curScore" value="4"/> <property name="student" ref="student"/> </bean> </beans>
-
同过全类名 使用反射 拿到类对象,通过类对象生成对象,调用对象的setXXX方法来为对象赋值。(反射原理)上述代码可简单理解为:
Student student(id) = new Student(); student.setAge(23); student.setStuName("张三"); student.setStuNo("1");
-
通过构造器方式
<?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 id="student" class="cn.spring.bean.Student"> <constructor-arg name="stuNo" value="1"/> <constructor-arg name="stuName" value="zs"/> <constructor-arg name="age" value="23"/> </bean> <bean id="course" class="cn.spring.bean.Course"> <constructor-arg name="curName" value="Spring"/> <constructor-arg name="curScore" value="4"/> <constructor-arg name="student" ref="student"/> </bean> </beans>
-
通过 P 方式
<?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" <!-- 使用p需要引入 --> xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="student" class="cn.spring.bean.Student" p:age="23" p:stuName="zs" p:stuNo="1"> </bean> <bean id="course" class="cn.spring.bean.Course" p:curName="Spring" p:curScore="4" p:student-ref="student"> </bean> </beans>
-
自动装配(只能用于 引用类型)(约定 > 配置)
- autowire=" Type " Type参数:
- default
- byName 通过ID
- byType 通过参数类型
- constructor 通过构造器
- no
<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" default-autowire="byName" <!-- 全局默认装配 --> > <bean id="student" class="cn.spring.bean.Student" autowire="byName" <!-- 局部装配优先级大于全局装配 --> > </bean> </beans>
- autowire=" Type " Type参数:
使用注解定义Bean
- 通过注解的形式将 bean 及相应的属性值 放入 IoC容器中
- 使用注解: @ component( component : 组件 (范围大))
- 注解的细分:
- @service 服务
- @Repository 仓库(Dao)
- @controller 控制
@Repository("student")
public class Student {
private int stuNo;
private String stuName;
private int age;
}
我们可以看见我们在 类 上 使用了 @Repository(仓库)来将 bean 放入IoC容器中,后面 student 是bean的 id
作用等效与:在XMl中:
<bean id="student" class="cn.spring.bean.Student" >
- 仅仅在 类 上使用 @Repository() 还不能将 bean 真正放入 IoC 容器中,需要在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/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
xmlns:context="http://www.springframework.org/schema/context"<!-- 首先导入context -->
>
<!-- 扫描 cn.spring.bean 包下类,若类上有 @Repository 则将该类加入 IoC 容器-->
<context:component-scan base-package="cn.spring.bean"/>
</beans>
使用注解实现声明式事务
- 搭建环境
- spring-tx 事务
- jdbc.jar 【数据库】
- commons-dbcp.jar 连接池到数据库
- commons-pool.jar 连接池
- spring-jdbc.jar spring 的jdbc
- aopalliance.jar aop
- 在方法前加入:
@Transactional(readOnly = false,propagation = Propagation.REQUIRED)
ring-tx