1、Spring
1.1简介
Spring理念:使现有的技术更加容易使用,整合了现有的技术框架,简化服务器开发
官网:https://spring.io/projects/spring-framework
下载地址:https://docs.spring.io/spring/docs/
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.2.6.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
1.2、优点
- Spring是一个开源的免费框架(容器)
- Spring是一个轻量级的,非入侵式的框架(引入不会影响之前程序的运行)
- 控制反转(IOC),面向切面编程(AOP),依赖注入(DI)
- 支持事务的处理,对框架整合的支持
总结:Spring就是一个轻量级的控制反转(IOC)和面向切面编程的框架
1.3、组成
1.4 扩展
Spring官网介绍:现代化的JAVA开发——基于Spring 的开发
-
SpringBoot
- 一个快速开发的脚手架
- 基于SpringBoot可以快速的开发单个微服务
- 约定大于配置!
-
SpringCloud
- SpringCloud是基于SpringBoot实现的
- SpringCloud是基于SpringBoot实现的
学习SpringBoot的前提——完全掌握Spring和SpringMVC承上启下的作用!!
弊端:发展太久之后,违背了原来的理念,配置繁琐
2、IOC(Inversion of Control)理论推导
IOC:控制反转,实现将组件间的关系从程序内部提到外部容器(spring的xml)来管理。
首先外部容器(spring.xml)中会动态的注册业务所需的对象(接口/类)
- UserDao接口
- UserDaoImpl实现类
- UserService 业务接口
- UserServiceImpl 业务实现类
用户调用业务类——业务类被调用后实际进行操作的是dao层;业务层的作用是调用dao层
此种方式:在业务中,用户的需求可能会影响原来的代码,当用户需求改变时,我们需要根据用户的需求去修改源代码——如果代码量十分大,则修改一次的成本代价非常昂贵
//业务层调用dao层
//除了继承之外类之间,调用别的类还有组合的概念,此时就将dao引到service中
private UserDao userDao=new UserDaoImpl();//需要根据用户需求的改变而改变
public void getUser(){
userDao.getUser();
}
解决问题方式:使用一个Set接口实现,已经发生了革命性的变化:程序此时被动接受对象
//业务层调用dao层
//除了继承之外类之间,调用别的类还有组合的概念,此时就将dao引到service中
private UserDao userDao;
//利用set方法进行动态实现值的注入
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
public void getUser(){
userDao.getUser();
}
-
加入set之前,程序是主动创建对象——此时创建什么类型的对象由程序员在程序中事先确定好
-
使用Set注入之后,程序不再具有主动性,而是变成被动接受对象——此时创建什么类型的对象由用户给出,创建对象的类型直到运行时才确定——不需要提前创建固定类型对象,而是创建实现类接口即可。
这种思想,从本质上解决了问题,程序员不用再去管理对象的创建了,此时系统的耦合性大大降低,可以更加专注在业务的实现上。——IOC原型,主动权交给用户
IOC本质
IOC控制反转,是一种设计思想,DI(依赖注入)是实现IOC的一种方法,也有人认为DI只是IOC的另一种说法,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己掌控,控制反转后将对象的创建移交给第三方——所谓的控制反转即,获得依赖对象的方式反转了
采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。
控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式,在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection,DI)
3、HelloSpring
Spring中对象是谁创建的?——由Spring创建,不需要new对象
对象的属性是怎么设置的?——由Spring容器设置
Spring创建对象的整个过程就叫做控制反转:
控制:谁来控制对象的创建,传统应用程序的对象是由程序本身控制创建的,使用Spring后对象是由Spring来创建。
反转:程序本身不创建对象,而变成被动的接收对象
**依赖注入(DI)**就是利用set方法来进行注入的。
IOC是一种编程思想,由主动的编程变成被动的接收,可以通过new ClassPathXmlApplicationContext浏览底层源码
使用Spring之后,想要实现不同的操作不需要再去程序中改动,只需要在xml配置文件中进行修改,所谓的IOC——对象由Spring来创建,管理,装配
4、IOC创建对象的方式
-
默认使用无参构造创建对象
-
假设我们要使用有参构造创建对象
如果没有无参构造器(且已设置有参构造器,此时默认的无参构造器将失效),则有一下三种方式在配置文件中对bean进行配置
示例有参构造器:
public User(String name,int ages){ this.name=name; ages=age; System.out.println("user的有参构造器"); }
1、使用index索引的方式
<!--index对应有参构造器中参数的位置,从0开始计数,不一定按顺序赋值--> <bean id="User" class="com.Dou.pojo.User"> <constructor-arg index="1" value="25"/> <constructor-arg index="0" value="DouDou"/> </bean>
2、使用Type参数类型的方式赋值
<!--基本数据类型可以直接写,其他的类型需要写明其路径,并且如果类型相同的两个参数一定要按照有参构造器中的顺序进行赋值,如果参数类型不相同且每个类型的参数只有一个,那么赋值顺序不影响最终结果--> <!--2:使用type,根据参数类型传入参数--> <bean name="User" class="com.Dou.pojo.User"> <constructor-arg type="java.lang.String" value="XiXi"/> <constructor-arg type="java.lang.String" value="man"/> </bean>
3、使用有参构造器中的参数名称赋值
<!--此方式要求name一定是等于有参构造器中方法参数的名称--> <!--3:使用与参数名称相对应的方式给有参构造器赋值--> <bean name="User" class="com.Dou.pojo.User"> <constructor-arg name="name" value="JonyJ"/> <constructor-arg name="ages" value="18"/> </bean>
在Spring容器中,每个对象都只有一个instance实例——此处用到了单例模式,
public void test02(){ //获得Spring容器 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //从容器中获得需要的对象 User user= (User)context.getBean("User"); User user2= (User)context.getBean("User"); //根据获得的对象调用方法 user.show(); System.out.println(user==user2); //结果为true,单例模式,在Spring容器中每个对象只有一个instance }
总结:在配置文件加载的时候,容器中管理的对象就已经初始化了——不管后面调用与否,bean.xml配置文件中配置的对象在加载文件的时候都会被实例化一份。
5、Spring配置
5.1、别名
<!--如果添加了别名,也可以使用别名获取对象,原名也可以-->
<alias name="User" alias="userNew"/>
5.2、Bean的配置
<!--bean配置文件介绍
id:bean的唯一标识符,也就相当于我们学的对象名
class:bean对象所对应的全限定名:包名+类型
name:也就是别名,而且name可以有多个取值,各值之间可以空格逗号分号分隔开都ok,name的值可用在后面getBean方法中调取对象的传入值
-->
<bean id="UserT" name="userT,u1 u2;u3" class="com.Dou.pojo.UserT">
<property name="name" value="Jiang"/>
</bean>
5.3、import
import一般用于团队开发使用,可以将多个配置文件,导入合并为一个
场景:项目中多个人开发,每个人负责不同的类开发,不同的人有不同的xml配置文件,可以通过import将所有人的beans.xml合并为一个总的——放置在一个总的xml文件中,比如applicationContext.xml文件中
<!--在一个总的xml配置文件中导入其他的配置文件-->
<import resource="beans.xml"/>
<import resource="beans1.xml"/>
<import resource="beans3.xml"/>
在import的过程中,总配置文件会自动合并相同的内容
//ClassPathXmlApplicationContext后面可以填写多个xml文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
6、DI(Dependency Injection,DI)依赖注入
6.1、构造器注入
就是前面提及的配置文件beans中通过构造器的方式创建对象
6.2、Set方式注入important
依赖注入的本质——Set注入?
- 依赖:bean对象的创建依赖于容器
- 注入: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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" class="com.Dou.pojo.Address">
<property name="address" value="新疆"/>
</bean>
<bean id="student" class="com.Dou.pojo.Student"&g