mapengpeng1999@163.com Spring框架

Spring:春天—>给软件行业带来春天。去百度百科Spring框架历史知识,去Spring官网。

2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。
Spring理念 : 使现有技术更加实用,本身就是一个大杂烩 ,整合现有的框架技术。
SSH:  Struct2 + Spring + Hibernate(全自动化持久框架)
SSM: SpringMVC + Spring + Mybatis(半自动化持久框架,可定制性高、sql更灵活,用的更多)
官网 : http://spring.io/
官方下载地址 : https://repo.spring.io/libs-release-local/org/springframework/spring/
GitHub : https://github.com/spring-projects

优点:

Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器(框架)。

1、Spring是一个开源免费的框架(容器)  ,Spring框架是为了简化Java的企业级应用开发而生。
2、Spring是一个轻量级的框架(体量小导入jar包就能用),非侵入式的(引入Spring不会改变代码原来的情况不会对原来项目产生影响) 
3、控制反转 IoC  , 面向切面 Aop(核心)
4、支持事务的处理(支持声明式事务因为AOP的原因),对框架整合的支持,所有的框架都可以整合进去。

弊端:发展太久了,违背了原来的理念,配置十分繁琐,人称“配置地狱”;
Spring是一个IOC(控制反转-Inversion Of Control )和AOP[面向切面编程]的容器(框架)。
DI[依赖注入]是IOC(控制反转)的另一种表述方式(另一种说法)。
IOC是一个容器,IOC容器会自动的将程序所需要的对象进行注入。

以往的形式:
	- 在编写Servlet的时候,需要调用Service
		- Service service = new ServiceImp();
		- 调用service中提供的方法
	- 在编写Service的时候,需要调用Dao
		- 【静态工厂方法】我们通过工厂类,提供静态方法,返回Dao对象
		- 就可以直接通过Dao对象去调用Dao中提供的方法
		
使用IOC后:
	- 在编写Servlet的时候,需要调用Service
		- 在Servlet中声明Service对象
			private Service service;
		- 就可以调用service中提供的方法
	   (这个service对象是个null调用service中提供的方法会报空指针异常,这个spring已经帮我们解决了,IOC容器会自动把这个对象传过来)
	- 在编写Service的时候,需要调用Dao
		- 在Service声明dao对象
			private Dao dao ;(只要声明这个对象就享有这个对象的方法,之前是要new这个对象出来,才能够享有这个对象提供的方法)
		- 就可以调用dao提供的方法
之前,程序是主动创建new对象,控制权在程序员手上。
使用IOC(控制反转)后,程序不再具有主动性,而是变成了被动的接受对象。
IOC这种思想,从本质上解决了问题,程序员不再用去管理对象的创建了,可以更加专注在业务的实现上。

IOC:反转控制,颠覆了以往获取对象的方式主动new对象,而变成了被动的接受对象。
DI[依赖注入]是IOC(控制反转)的另一种表述方式(另一种说法)。
AOP:面向切面编程,是对面向对象编程(OOP)的一种补充。

对于AOP常用的就是处理数据库的事务(支持声明式事务因为AOP的原因)和完成限流(这个方法在某段时间内只限制它调用几次)。

原来: 我们在获取对象时,都是采用 new 的方式。是主动的。 
现在: 我们在获取对象时,是去IOC容器中拿。是被动的。
这种被动接收的方式获取对象的思想就是IOC(控制反转),它是 spring 框架的核心之一。 
1.Spring是非侵入性框架:可以任意的和第三方框架结合使用,不会排斥其他框架。
Spring是一个容器(IOC容器),这个容器中管理了所有bean的生命周期。
2.Spring是一个轻量级框架:开发可以不依赖于SpringAPI,
使用Spring的时候,不需要继承Spring提供的任何的类或者实现Spring提供的任何接口,
就可以享有Spring提供的功能。(就好像没有使用Spring,但又享有Spring提供的功能)
3.Spring是一个一站式框架:(就是所有的技术都给你提供好了)
一站式表示Spring提供了JavaEE的一整套解决方案,你只要使用Spring,就可以不用去使用其他的任何框架,就能够完成JavaEE开发,
控制层Spring提供了SpringMVC,数据访问层Spring提供了Spring JDBCTemplate和SpringData,业务层就是使用SpringAOP完成声明式事务管理。
Spring Data:  Spring 的一个子项目,用于简化数据库访问。Spring Data是一个框架,Spring JDBCTemplate是一个工具。

Spring模块:

在这里插入图片描述

左上角那块代表Spring处理业务层,右上角那块代表SpringMVC处理控制层,下面那块代表dao数据访问层。
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在Core container核心容器之上,
核心容器定义了创建、配置和管理 bean 的方式 。

在这里插入图片描述

组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

1.核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。
BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

2.Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

3.Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。
可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。
通过使用 Spring AOP,不用依赖组件,就可以将声明式事务管理集成到应用程序中。

4.Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。
异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。
Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

5.Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

6.Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。
所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

7.Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,
MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

在这里插入图片描述

扩展:Spring Boot与Spring Cloud

Spring Boot 是 Spring 的一套快速配置脚手架,可以基于Spring Boot 快速开发单个微服务;
Spring Cloud是基于Spring Boot实现的;学习Spring Boot的前提,需要完全掌握Spring和SpringMVC;
Spring Boot专注于快速、方便集成的单个微服务个体,Spring Cloud关注全局的服务治理框架;
Spring Boot使用了约束大于配置的理念,很多集成方案已经帮你选择好了,能不配置就不配置 , Spring Cloud很大的一部分是基于Spring Boot来实现,
Spring Boot可以离开Spring Cloud独立使用开发项目,但是Spring Cloud离不开Spring Boot,属于依赖的关系。
SpringBoot在SpringClound中起到了承上启下的作用,如果你要学习SpringCloud必须要学习SpringBoot。

Spring开发环境的搭建

Spring开发我们可以使用Eclipse,但是Eclipse中必须安装Spring开发插件:Spring tool suite,
或者直接到网络上下载安装了插件的Eclipse,这种Eclipse就叫做Spring tool suite。
打开Spring tool suite编写,新设置个工作空间目录(如workspace(Spring tool suite))来存放编写的项目。
现阶段用java project,等spring mvc再用动态web工程。找到自带的服务器delete删除,
再window,preferences,server,runtime environme将环境移除。
下载Spring tool suite压缩包后解压就能用,前提是电脑环境变量必须配置JAVA_HOME,
就是和Eclipse解压一样要配置JAVA_HOME,前面安装Eclipse时已经配置好JAVA_HOME,此处不需再配置环境变量。

原生获取对象的方式

new个java project项目,在项目下建包在包下创建类,写好属性后创建相应的get()和set()方法,
再创建有参构造器(Generate Constractor using Fields)和
无参构造器(Generate Constractor from Superclass)和
Generate toString方法( toString方法测试时比较方便点)

package com.wanbangee.spring;
public class Person {
	private String name;
	private Integer age;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public Person(String name, Integer age) {   //有参构造器
		super();
		this.name = name;
		this.age = age;
		System.out.println(“有参构造器”);
	}
	public Person() {   //无参构造器
		System.out.println(“无参构造器”);
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
}

public static void main(String[] args) {
		//1 获取Person对象
		Person person = new Person();
		//2 设置对象的属性值
		person.setName("蜘蛛精");
		person.setAge(18);
		//使用对象
		System.out.println(person);
	}

Spring获取对象的方式

步骤1:导包,最基本Spring的开发也需要以下的jar文件
commons-logging-1.1.3.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
右击项目名new个Folder文件夹,将其命名为lib,将以上jar文件copy进该目录后,
再添加到类路径中Build path, Add to Build path。(按住Ctrl+鼠标左击,可同时点击复制多个)
(java project项目要手动将jar包添加到类路径,动态web项目会自动将jar包添加到类路径)
后面的xml配置文件也是右击项目名new个Source Folder文件夹,将其命名为conf,用来放类路径下的配置文件。
src写代码,conf放类路径下的配置文件,运行后发现conf中配置文件和src下面的代码都在bin目录下。真正类路径是bin目录。
步骤2:创建Spring的配置文件(在讲解注解配置方式之前都使用配置xml文件的形式)。
在src目录下(或在conf目录下)others里搜索spring找到Spring Bean Configuration File 文件。
在学习知识点的时候,spring配置文件的名称和学习内容相关, 
实际开发中Spring的配置文件一般取名都叫做applicationContext.xml。

在这里插入图片描述

步骤3:在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:表示配置一个bean,这个bean会在IOC容器启动的时候,被IOC容器加载(实例化),并且在IOC容器中管理这个bean
			- id : bean的名称,也就是对象名,是一个唯一的名称
			- class: 这个bean对应的类型的全类名,就是包名加类名
表示配置bean的类型,这里使用全类名【使用全类名反射获得Person类对象】
				- name : 属性名【对应的是JavaBean风格的属性名】
				- value : 需要设置的属性值,只能放字面值,不能放对象
				字面值:指在程序中无需变量保存,可直接表示为一个具体的数字或字符串的值,
				比如,在a=b+2这个语句中,2就是一个字面值,它本身就是一个具体的值。
				- property : 表示属性注入,配置IOC容器中管理的bean的对象的属性值,property标签属性注入时会调用setter方法
		细节:
			- name : 属性名【对应的是JavaBean风格的属性名,也就是对应的setter方法的属性名】
			<!--注意: 属性是set方法后面的那部分 , 首字母小写,如setAge方法,其属性名是age-->
			- 通过bean的配置,IOC容器才有对象。IOC容器中可以配置多个对象,就是配置多个bean
		 细节1 : SpringIOC容器会使用全类名反射创建Person类对象  <bean id="person" class="com.wanbang.hello.Person">
		 细节2 : property 标签进行属性注入会调用setter方法完成
		 细节3 : property 标签设置的属性名是JavaBean风格的属性名
		 细节4 : bean的对象是在IOC容器初始化的时候就被创建
		 细节5 : 根据bean的类型获得bean的对象,Person person = act.getBean(Person.class) 
		 如果IOC容器中有两个相同类型的bean对象存在(全类名相同),则会报错。
		 expected single matching bean but found 2: person,person2  意思是需要单例的bean对象,却找到两个。
   现在想要获得其中的某一个的情况下,怎么处理呢? 这时可以根据bean的名称获得bean的对象:
		 Person person = (Person)act.getBean("person2");//这个方法返回是object类型,要强制转换
	 -->
	<bean id="person" class="com.wanbang.hello.Person">
		<property name="age" value="20"></property>
		<property name="name" value="白骨精"></property>
	</bean>
	<bean id="person2" class="com.wanbang.hello.Person">
		<property name="age" value="21"></property>
		<property name="name" value="紫霞仙子"></property>
	</bean>
</beans>
步骤4:在main主方法中编写测试程序
在启动IOC容器时,是根据类路径下(src目录下或conf目录下)的spring配置文件来创建的。
	如果Spring的配置文件路径并不是直接在类路径下。src才是类路径,我们需要加上绝对路径,
	假设配置文件放在包下,则("applicationContext.xml")中内容要替换成“com/wanbangee/helloworld/applicationContext.xml"
	如果Spring的配置文件没有在类路径下,假设放在桌面,
	使用FileSystemXmlApplicationContext,表示从文件系统加载xml配置文件
	就是将ClassPathXmlApplicationContext("applicationContext.xml");
	替换成FileSystemXmlApplicationContext("桌面文件地址加绝对路径如c:\\Users\Admin\applicationContext.xml");
	在FileSystemXmlApplicationContext构造器中传入配置文件在文件系统的绝对路径 
		
		//1.启动SpringIOC容器,并获得这个容器对象
		//ApplicationContext就是SpringIOC容器,act就是这个容器对象。//从类路径中加载Spring的配置文件
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
		//2 .从IOC容器中获取bean对象
		//Person person = act.getBean(Person.class); //根据bean的类型获得bean的对象
		Person person = (Person) act.getBean("person"); //这个方法返回是object类型,要强制转换
		//通过bean的名称获得bean的对象(就是用bean的id来区分不同bean对象)
		//3 .使用bean
		System.out.println(person);
	}
}

类名.class得到对象是反射获取方式。
getBean(Class <T>)  T,返回泛型T就是bean类型
//Person person = act.getBean(Person.class); //根据bean的类型获得bean的对象
Person person = (Person) act.getBean("person"); //通过bean的名称获得bean的对象,这个方法返回是object类型,要强制转换
除了属性名称和配置文件地址的细节外,我们还需要注意的细节:
bean对象是IOC容器产生的。
- bean对象是什么时候被实例化的?
- 在IOC容器启动时,bean对象就实例化了。 在配置文件加载的时候,容器中管理的bean对象就已经初始化了。
构造器是用来构造对象的,调用了构造器就一定创建了对象。
- bean对象实例化的时候调用的是哪个构造方法?
--调用的是无参数的构造器
- bean对象的属性值是怎么设置上的? property属性注入时会调用setter方法
- 通过Bean类中的setter方法设置的

现在如果我想要一个对象,不需要再创建new对象,而是直接去IOC容器中获取。

类与类的关系

public class Person {
	private String name;
	private Integer age;
	private Car car;

public class Car {
	private String barnd;
	private Double price;
- ref : 引用IOC容器中其他的bean(对象)

	<bean id="person" class="com.wanbangee.helloworld.Person">
		<property name="age" value="19"></property>
		<property name="name" value="紫霞仙子"></property>
		<property name="car" ref="car"></property>
	</bean>    //ref引用bean为car的对象
	
	<bean id="car" class="com.wanbangee.helloworld.Car">
		<property name="barnd" value="Audi"></property>
		<property name="price" value="300000"></property>
	</bean>
		//1 .启动SpringIOC容器,并获得这个容器对象
		ApplicationContext act = new ClassPathXmlApplicationContext("helloworld.xml");
		//2 .从IOC容器中获取bean对象
		Person person = (Person) act.getBean("person");//这个方法返回是object类型,要强制转换
		//3 .使用bean
		System.out.println(person.getCar().getBarnd());
		
这是使用IOC容器去设置bean与bean之间的关系,在使用IOC之前,我们必须单独的设置关系:
		Person person = new Person();
		Car car = new Car();
		car .setBarnd("Bnze");
		car.setPrice(400000.0);
		person.setName("唐僧");
		person.setCar(car);//手动建立两个对象之间的关系
		System.out.println(person.getCar().getBarnd());

IOC(DI)概述

IOC :Inversion of Control,意思是反转资源的获取方式,传统的资源获取方式要求组件向容器发起请求,
请求查找资源,作为回应,容器适时的返回资源。而应用了IOC之后,则是容器主动的将资源推送给需要的组件,
组件所需要的做的就是选择一种合适的方式来接收资源,这种形式也称为查找的被动方式。
DI:Dependency Injection【依赖注入】,是IOC另一种表述方式(另一种说法),
即组件以一些预定好的方式接收来自容器的资源注入。


思考:
bean 对象是谁创建的 ?  【bean 对象是由Spring IOC容器创建的,在IOC容器启动时创建。】
bean 对象的属性是怎么设置的 ?  bean 对象的属性是由Spring IOC容器设置的,通过调用Bean类中的setter方法设置的。
这个过程就叫控制反转 :
控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring IOC容器来创建的
反转 : 程序本身不创建对象 , 而变成被动的接收对象 
DI依赖注入 : 就是利用setter方法来进行属性注入的。

IOC是一种编程思想,由主动的编程变成被动的接收
可以通过newClassPathXmlApplicationContext去浏览一下底层源码。

IOC的前世今生

- 原始社会:分离接口与实现,相当于说,在原始社会,我需要一把斧头,需要两个实现,一个是制作头,一个是制作柄,
站在我的角度,我们必须知道斧头的制作细节,才能够拥有一把斧头。
IOC前世:分离接口和实现。接口对象new接口实现类,要知道接口和实现类才能得到对象。

- 封建社会:采用工厂设计模式,相当于说,在封建社会,我需要一把斧头,我只需要拿着银子去铁匠铺换就成。
采用了工厂设计模式之后,站在使用者的角度而言,会相比原始社会方便很多,不需要知道斧头制作的细节就可以拥有斧头。
IOC前世:采用工厂设计模式。要有dao和工厂类,不用实现类。

- 共产主义社会:采用的是IOC,或者叫做控制反转,相当于共产主义社会,我需要一把斧头,我不需要会制作斧头,
我也不需要调用工厂,而是在门口放一个装斧头的框,容器自动的将斧头放到框中给你。
IOC今生:采用IOC反转控制,DI(依赖注入)是IOC的另一种说法。

IOC是一个容器,IOC容器会自动的将程序所需要的对象进行注入。
通过bean的配置,IOC容器才有对象。IOC容器可以配置多个对象,就是配置多个bean
那么知道了这些之后,在以后的开发中,对于Dao而言,我们就不需要工厂了,

IOC和DI 在以后的面试过程中,经常会被问到,大家一定要理解IOC的概述和前世今生。

IOC本质

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,(实现IOC的方式有很多)
也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 
对象的创建与对象间的依赖关系完全靠编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,
个人认为所谓控制反转就是:获得依赖对象的方式反转了。

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC。

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

在这里插入图片描述

采用XML方式配置Bean的时候,Bean的定义信息是和实现分离的,而采用注解的方式可以把两者合为一体,
Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。
在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值