1、Spring(概述)
1.1、简介
-
Spring:春---->给软件行业带来春天
-
2002年首次推出Spring框架雏形: interface21框架
-
Spring框架即以interface2004年3月24日,以21框架为基础,经过重新设计,不断丰富其内涵,发布1.0正式 版
-
Rod Johnson,Spring Framework创始人,著名作者。很难想象Rod Johnson学历真的让很多人大吃一惊。他是悉尼大学的博士,但他的专业不是计算机,而是音乐。
-
spring理念:使现有的技术更加容易使用,本身是一个大杂烩,整合了现有的技术框架
-
SSH : Struct2 Spring Hibernate
-
SSM:SpringMvc Spring Mybatis
官网: https://spring.io/projects/spring-framework#overview
官方下载地址: http://repo.spring.io/release/org/springframework/spring GitHub: https://github.com/spring:projects/spring-framework
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.11</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.11</version> </dependency>
1.2、优点
- Spring免费开源框架(容器) !
- Spring是一个轻 量级,非入侵框架!
- 支持处理事务,支持框架整合!
总结一句话:
1.3、组成
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-6jS4VKTG-1656760867323)(Spring.assets/27c714d4c6e88d1a6a5ea8a72ff3281a.png)]
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-J73r096m-1656760867323)(Spring.assets/5c2586a36ed1cfd9fc4eaefc0a78ce52.png)]
组成 Spring 框架的每个模块(或组件)可以单独存在,也可以与其他一个或多个模块联合实现。每个模块的功能如下:
-
:提供核心容器 Spring 框架的基本功能。核心容器的主要部件是
BeanFactory
,实现工厂模式。BeanFactory
使用控制反转(IOC) 该模式将应用程序的配置和依赖性规范与实际应用程序代码分开。 -
:Spring 上下文是配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,如 JNDI、EJB、电子邮件、国际化、验证和调度功能。
-
:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。因此,它很容易使用 Spring 任何支持框架管理的支持 AOP的对象。Spring AOP 模块为基于 Spring 应用程序中的对象提供事务管理服务。通过使用 Spring AOP,声明性事务管理可以集成到应用程序中,无需依赖组件。
-
Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可以用来管理不同数据库供应商抛出的异常处理和错误信息。异常层次结构简化了错误处理,大大降低了需要编写的异常代码数量(如开关连接)。Spring DAO 的面向 JDBC 异常遵循一般 DAO 层次结构异常。
-
:Spring 多个框架插入 ORM 提供框架 ORM 对象关系工具包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵循 Spring 一般事务和 DAO 层次结构异常。
-
:Web 上下文模块基于应用程序上下文模块 Web 应用程序提供上下文。Spring 框架支持与 Jakarta Struts 的集成。Web 该模块还简化了处理多部分请求和将请求参数绑定到域对象的工作。
-
:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过战略界面,MVC 框架变得高度可配置,MVC 大量的视图技术包括 JSP、Velocity、Tiles、iText 和 POI。
1.4、拓展
在Spring官网有这个介绍:现代化Java开发!说白就是基于Spring的开发!
[外链图片存储失败,源站可能有防盗链机制,建议保存图片直接上传(img-M2gdCkqX-1656760867323)(Spring.assets/a42b4e5df07e29b66de4d0d053ba9b73.png)]
-
Spring Boot
-
脚手架的快速开发
-
基于Spring Boot能够快速开发单个微服务
-
协议大于配置
Spring Cloud
- Spring Cloud是基于Spring Boot实现的
- 因为现在大多数公司都在使用它SpringBoot进行快速开发,学习SpringBoot的前提 ,需要完全掌握Spring及SpringMVC!承上启下的作用!
2、IOC理论推导
新的空白maven项目
2.1、分析实现
我们先用我们原来的方式写一段代码 .
- 先写一个UserDao接口
public interface UserDao {
public void getUser(); }
- 再去写Dao的实现类
ublic class UserDaoImpl implements UserDao {
@Override
public void getUser() {
System.out.println("获取用户数据");
}
}
- 然后去写UserService的接口
public interface UserService {
public void getUser();
}
- 最后写Service的实现类
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
- 测试一下
@Test
public void test(){
UserService service = new UserServiceImpl();
service.getUser();
}
这是我们原来的方式 , 开始大家也都是这么去写的对吧 . 那我们现在修改一下 .
把Userdao的实现类增加一个
public class UserDaoMySqlImpl implements UserDao {
@Override
public void getUser() {
System.out.println("MySql获取用户数据");
}
}
紧接着我们要去使用MySql的话 , 我们就需要去service实现类里面修改对应的实现 .
public class UserServiceImpl implements UserService {
private UserDao userDao = new UserDaoMySqlImpl();
@Override
public void getUser() {
userDao.getUser();
}
}
在假设, 我们再增加一个Userdao的实现类 .
public class UserDaoOracleImpl implements UserDao {
@Override
public void getUser() {
System.out.println("Oracle获取用户数据");
}
}
那么我们要使用Oracle , 又需要去service实现类里面修改对应的实现 . 假设我们的这种需求非常大 , 这种方式就根本不适用了, 甚至反人类对吧 , 每次变动 , 都需要修改大量代码 . 这种设计的耦合性太高了, 牵一发而动全身 .
我们可以在需要用到他的地方 , 不去实现它 , 而是留出一个接口 , 利用set , 我们去代码里修改下 .
public class UserServiceImpl implements UserService {
private UserDao userDao;
// 利用set实现
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
@Override
public void getUser() {
userDao.getUser();
}
}
使用set接口实现
- 之前,程序是主动创建对象!控制权在程序猿手上!
- 使用了set注入后,程序不再具有主动性,而是变成了被动的接受对象,系统耦合性大大降低,可以更加的专注在业务的实现上,这是IOC的原型
现在去我们的测试类里 , 进行测试 ;
@Test
public void test(){
UserServiceImpl service = new UserServiceImpl();
service.setUserDao( new UserDaoImpl() );
service.getUser();
service.setUserDao( new UserDaoMySqlImpl() );
service.getUser();
//那我们现在又想用Oracle去实现呢
service.setUserDao( new UserDaoOracleImpl() );
service.getUser();
}
大家发现了区别没有 ? 可能很多人说没啥区别 . 但是同学们 , 他们已经发生了根本性的变化 , 很多地方都不一样了 . 仔细去思考一下 , 以前所有东西都是由程序去进行控制创建 , 而现在是由我们自行控制创建对象 , 把主动权交给了调用者 . 程序不用去管怎么创建,怎么实现了 . 它只负责提供一个接口 .
这种思想 , 从本质上解决了问题 , 我们程序员不再去管理对象的创建了 , 更多的去关注业务的实现 . 耦合性大大降低 . 这也就是IOC的原型 !
2.2、IOC本质
,也有人认为DI只是
IoC的另一种说法。没有IoC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A9CyH5CZ-1656760867324)(Spring.assets/01826c23d18ee93aceaf23a3c73c07c7.png)]
,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。
Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sZnNZiB8-1656760867324)(Spring.assets/c73f2660c2455df0b11c1c601b01def6.png)]
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为- -体, Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
3、HelloSpring
3.1、导入jar包
spring 需要导入commons-logging进行日志记录 . 我们利用maven , 他会自动下载对应的依赖项 .
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.11</version>
</dependency>
3.2、编写代码
-
编写一个Hello实体类
public class Hello { private String string; public String getString() { return string; } public void setString(String string) { this.string = string; } @Override public String toString() { return "Hello{" + "string='" + string + '\'' + '}'; } }
- 编写我们的spring文件 , 这里我们命名为beans.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 https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="hello" class="com.study.pojo.Hello">
<property name="string" value="Spring"/>
</bean>
</beans>
- 我们可以去进行测试了 .
@Test
public void test(){
//解析beans.xml文件 , 生成管理相应的Bean对象
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//getBean : 参数即为spring配置文件中bean的id .
Hello hello = (Hello) context.getBean("hello");
System.out.println(hello.toString());
}
3.3、思考问题?
- Hello 对象是谁创建的? hello对象是由Spring创建的
- Hello 对象的属性是怎么设置的? hello对象的属性是由Spring容器设置的,
这个过程就叫控制反转:
-
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后 ,对象是由Spring来创建的.
-
反转:程序本身不创建对象,而变成被动的接收对象
依赖注入:就是利用set方法来进行注入的.
IOC是一种编程思想,由主动的编程变成被动的接收.
可以通过newClassPathXmlApplicationContext去浏览一下底层源码 .
4、IOC创建对象的方式
4.1.通过无参构造方法来创建
- User.java
public class User {
private String name;
public User() {
System.out.println("User的无参构造函数!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("User:"+name);
}
}
- beans.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">
<bean id="user" class="com.kuang.pojo.User">
<property name="name" value="study"/>
</bean>
</beans>
- 测试类
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//在执行getBean的时候, user已经创建好了 , 通过无参构造
User user = (User) context.getBean("user");
//调用对象的方法 .
user.show();
}
4.2.通过有参构造方法来创建
- User . java
public class User {
private String name;
public User() {
System.out.println("User的无参构造函数!");
}
public User(String name) {
this.name = name;
System.out.println("User的有参构造函数!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("User:"+name);
}
}
- beans.xml 有三种方式编写
<!-- 第一种根据index参数下标设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
<!-- index指构造方法 , 下标从0开始 -->
<constructor-arg index="0" value="kuangshen2"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
<!-- name指参数名 -->
<constructor-arg name="name" value="kuangshen2"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="userT" class="com.kuang.pojo.UserT">
<constructor-arg type="java.lang.String" value="kuangshen2"/>
</bean>
- 测试
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
//在执行getBean的时候, user已经创建好了 , 通过有参构造
User user = (User) context.getBean("user");
//调用对象的方法 .
user.show();
}
5、Spring配置
5.1、别名
<bean id="user" class="com.study.pojo.User">
<constructor-arg type="java.lang.String" value="root"/>
<constructor-arg type="java.lang.String" value="123456"/>
</bean>
<!--如果添加了别名,也可以通过别名获取到这个对象-->
<alias name="user" alias="userNew"/>
5.2、Bean的配置
-
id:bean的id标识符
-
class:bean对象所对应的类型(包名+类名)
-
name:别名,更高级,可以同时取多个别名。
<!--bean就是java对象,由Spring创建和管理--> <!-- id 是bean的标识符,要唯一,如果没有配置id,name就是默认标识符 如果配置id,又配置了name,那么name是别名 name可以设置多个别名,可以用逗号,分号,空格隔开 如果不配置id和name,可以根据applicationContext.getBean(.class)获取对象; class是bean的全限定名=包名+类名 --> <bean id="hello" name="hello2 h2,h3;h4" class="com.kuang.pojo.Hello"> <property name="name" value="Spring"/> </bean>
5.3、import
这个import,一般用于团队开发,可以将多个配置文件,导入合并一个
假设,项目中有多个人开发,这三个人负责不同的人开发,不同的类需要注册在不同的bean中,我们可以利用import,将所有人的beans.xml合并为总的
-
张三
-
李四
-
王五
-
applicationContext.xml
使用的时候使用总的就可以了
<import resource="beans.xml"/>
<import resource="beans2.xml"/>
<import resource="beans3.xml"/>
6、DI依赖注入
- 依赖注入(Dependency Injection,DI)。
- 依赖 : 指Bean对象的创建依赖于容器 . Bean对象的依赖资源 .
- 注入 : 指Bean对象所依赖的资源 , 由容器来设置和装配 .
6.1、构造器注入
6.2、通过set方式注入【重点】
- 依赖注入:Set注入!
- 依赖:bean对象的创建依赖于容器
- 注入:bean对象中的所有属性,由容器来注入
【环境搭建】
-
Address
public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "Address{" + "address='" + address + '\'' + '}'; } }
-
Student
- 构造:有参、无参;
- set、get;
- toString();
public class Student {
private String name;
private Address address;
private String[] books;
private List<String> hobbies;
private Map<String,String> card;
private Set<String> games;
private Properties info;
private String wife;
}
-
beans.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"> <bean id="address" class="com.study.pojo.Address"> <property name="address" value="岳阳 标签:
各式连接器fce17fce连接器