一、Sping简介
1、概述
1、Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。
2、Spring是一个面向对象设计层面的开发框架(基本上都是运行在后台),其本身提供有一个完善的设计容器,利用此容器可以帮助开发者实现对象的管理、线程同步处理、依赖关系的配置等。
2、Spring框架特点
1、非侵入式:基于Spring开发的应用中的对象可以不依赖与Spring的API
2、控制反转
:IoC(Inversion of control),指的是将对象的创建权交由Spring框架来管理,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系。在使用Spring之前,对象的创建都是在代码中new创建。
3、依赖注入
:DI(Dependency Injection),应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源。依赖的对象不需要手动调用setXXX方法去设置值,通过配置自动赋值。
4、容器
:Spring负责创建和管理对象(Bean)的生命周期和配置。
5、面向切面编程
:AOP(Aspect Oriented Programming),能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可扩展性和可维护性。
6、组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在Spring中可以使用XML和Java注解组合这些对象。
3、Spring体系结构
1、Code Container(Spring的核心容器):
Beans
:提供了框架的基础部分,包括控制反转和依赖注入。 Context
:上下文模块,建立在Core和Beans模块的基础上,它以一种类似于JNDI注册的方式访问对象。集成Beans模块功能并添加资源绑定、数据验证、国际化、Java EE支持、容器生命周期、事件传播等,ApplicationContext接口是上下文模块的焦点。
2、Data Access/Integration(数据访问/集成):
JDBC
:提供了一个JDBC的样例模板,使用这些模板能消除传统冗长的JDBC编码还有必须的事务控制,而且能享受到Spring管理事务的好处。 OXM
:提供了一个支持Object/XML映射的抽象层实现,如JAXB、Castor、XMLBeans、JiBX和XStream。将Java对象映射成XML数据,或者将XML数据映射成Java对象。 Transactions
:事务模块,支持编程和声明式事务管理。
3、Web模块:
Web
:为Spring提供了最基础的Web支持,主要建立在核心容器之上,通过Servlet或者Listeners来初始化IoC容器,也包含一些与Web相关的支持。 WebSocket
:与Web前端进行全双工通信的协议。
4、AOP、Aspects、Instrumentation和Messaging模块:
AOP
:提供了面向切面编程实现,提供比如日志记录、权限控制、性能统计等通用功能和业务逻辑分离的技术,并且能动态的把这些功能添加到需要的代码中,这样各司其职,降低业务逻辑和通用功能的耦合。 Instrumentation
:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
5、Test模块:Spring支持Junit和TestNG测试框架,而且还额外提供了一些基于Spring的测试功能,比如在测试Web框架时,模拟Http请求的功能。
二、Spring简单示例搭建
1、创建一个Maven工程
1、新建一个Project
2、填写好信息,点击结束
2、引入Spring的POM依赖
<?xml version="1.0" encoding="UTF-8"?>
< project xmlns = " http://maven.apache.org/POM/4.0.0"
xmlns: xsi= " http://www.w3.org/2001/XMLSchema-instance"
xsi: schemaLocation= " http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
< parent>
< artifactId> Learning</ artifactId>
< groupId> com.itan</ groupId>
< version> 1.0-SNAPSHOT</ version>
</ parent>
< modelVersion> 4.0.0</ modelVersion>
< artifactId> spring-core</ artifactId>
< properties>
< maven.compiler.source> 8</ maven.compiler.source>
< maven.compiler.target> 8</ maven.compiler.target>
< spring-framework.version> 5.2.7.RELEASE</ spring-framework.version>
</ properties>
< dependencies>
< dependency>
< groupId> org.springframework</ groupId>
< artifactId> spring-context</ artifactId>
< version> ${spring-framework.version}</ version>
< scope> compile</ scope>
</ dependency>
</ dependencies>
</ project>
3、新建一个实体类(Bean)类
public class User {
private String name;
private String sex;
private Integer age;
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public String getSex ( ) {
return sex;
}
public void setSex ( String sex) {
this . sex = sex;
}
public Integer getAge ( ) {
return age;
}
public void setAge ( Integer age) {
this . age = age;
}
}
4、Spring配置文件
1、在resources目录下新增一个配置文件,命名建议spring-config.xml或者applicationContext.xml,这就是Spring的核心配置文件。
<?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.itan.beans.User" />
</ beans>
5、测试
public class Test1 {
public static void main ( String [ ] args) {
ApplicationContext context = new ClassPathXmlApplicationContext ( "spring-config.xml" ) ;
User user = ( User ) context. getBean ( "user" ) ;
User user1 = context. getBean ( "user" , User . class ) ;
User user2 = context. getBean ( User . class ) ;
System . out. println ( user) ;
System . out. println ( user1) ;
System . out. println ( user2) ;
}
}
三、IoC容器
1、IoC概述
1、Spring的核心机制就是IoC(Inversion of Control),即“控制反转”或“反转控制”,就是将原本在程序中手动创建对象的权力,交由Spring框架来管理,并由容器根据配置文件去创建实例和管理各个实例之间的依赖关系,在需要的时候进行依赖注入。对象与对象之间松散耦合。
2、交给Spring管理的对象被称为Bean,Bean对象存放的地方被称为IoC容器,或者Bean工厂
。
3、最直观的意思:IoC让对象的创建不用去new了,可以由Spring自动生产,使用Java的反射机制,根据配置文件在运行时动态的创建对象和管理对象,并调用对象的方法。
2、Spring Bean
1、当配置好需要交给IoC管理的对象,并启动IoC容器,就可以从IoC容器中获取我们需要的对象了;其中,交给IoC容器管理的对象称为Bean,或者说Bean是由IoC容器进行实例化、组装和管理的对象。
2、Spring IoC容器管理一个或多个Bean。这些Bean是用我们提供给容器的配置元数据创建的,配置元数据可以通过以下几种形式来表示:
XML:最原始的Spring配置方式,现在很少用,被下面两种方式取代。 Java配置:可以通过Java代码配合注解使用,比如@Configuration、@Bean、@Import、@DependsOn
等注解
3、在Spring IoC容器本身中,我们定义的配置元数据创建的Bean对象会转为BeanDefinition对象,BeanDefinition会记录下所有解析到的Bean定义,将解析结果保存起来的好处就是此后就不至于每次用到配置信息的时候都去解析一遍配置元数据
。BeanDefinition中包含以下数据:
包限定类名:通常是被定义的Bean的实际实现类。 对其他Bean的引用:Bean可能需要引用其他的Bean来完成它的工作,这些引用也称为协作者或依赖关系。
3、通过XML装配Bean
1、将Bean的信息配置.xml文件里
,通过Spring加载文件为我们创建Bean。这种方式出现很多早前的SSM项目中,将第三方类库或者一些配置工具类都以这种方式进行配置,主要原因是由于第三方类不支持Spring注解。
2、优缺点说明:
3、通过<bean />
标签在xml文件中配置Bean,常用的属性配置说明如下:
id
:Bean在spring容器的唯一标识,spring容器中不可能同时存在两个相同的id。 name
:设置Bean的别名,可以有多个,用“,”或“;”或空格来区分多个name,不同Bean的name和id都不能一样 lazy-init
:Bean的实例化时机,是否延迟加载,设置只对scope属性为singleton的Bean起作用,非单例不实例化;false表示立即加载,在spring启动时,立刻进行实例化;true表示延迟加载,设置为true的Bean不会在ApplicationContext启动时提前被实例化,而是在第一次向容器通过getBean获取Bean时实例化的。 destory-method
:在Bean实例销毁前调用的方法,只对scope=“singleton”的Bean起作用,并且方法的参数个数不能超过1,并且参数类型只能为boolean。 factory-bean
与factory-method
:指定由哪个工厂哪个方法完成Bean的创建。
4、上面目录二中的示例代码中就是基于XML装配Bean。
4、通过Java配置装配Bean
1、将类的创建交给我们配置的JavcConfig类来完成,Spring只负责维护和管理,采用纯Java创建方式。其本质上就是把在XML上的配置声明转移到Java配置类中。
2、优缺点说明:
优点
:适用于任何场景,配置方便,因为是纯Java代码,扩展性高,十分灵活
3、实现步骤:
创建一个配置类, 添加@Configuration
注解声明为配置类。 注意:实例类不需要加任何注解。
@Configuration
public class BeanConfig {
@Bean
public User user ( ) {
return new User ( ) ;
}
}
public class Test2 {
public static void main ( String [ ] args) {
ApplicationContext context = new AnnotationConfigApplicationContext ( BeanConfig . class ) ;
User user = context. getBean ( "user" , User . class ) ;
System . out. println ( user) ;
}
}
5、通过注解装配Bean
1、通过在类上加注解的方式,来声明一个类交给Spring管理,Spring会自动扫描带有@Component,@Controller,@Service,@Repository
这四个注解的类,然后帮我们创建并管理,前提是需要先配置Spring的注解扫描器。
2、优缺点说明:
3、实现步骤:
对类添加@Component
相关的注解,比如@Controller、@Service、@Repository
XML配置扫描的包:<context:component-scan base-package='com.itan.beans'>
代码设置扫描的包:new AnnotationConfigApplicationContext("com.itan.beans")
package com. itan. beans ;
import org. springframework. stereotype. Component ;
@Component
public class User {
private String name;
private String sex;
private Integer age;
public String getName ( ) {
return name;
}
public void setName ( String name) {
this . name = name;
}
public String getSex ( ) {
return sex;
}
public void setSex ( String sex) {
this . sex = sex;
}
public Integer getAge ( ) {
return age;
}
public void setAge ( Integer age) {
this . age = age;
}
}
public class Test3 {
public static void main ( String [ ] args) {
ApplicationContext context = new AnnotationConfigApplicationContext ( "com.itan.beans" ) ;
User user = context. getBean ( "user" , User . class ) ;
System . out. println ( user) ;
}
}
四、依赖注入(DI)
1、概述
1、在实际应用中,Bean对象不可能是单一的,往往一个Bean对象,还会依赖很多其他的Bean的属性。这就有了依赖注入的概念,由DI来维护Bean之间的依赖关系,并且自动注入需要的依赖项,使用DI之后,具有依赖关系的对象之间没有了强耦合关系,对象不需要主动查找、获取其依赖项,甚至都不用知道依赖项的具体位置,它们都在容器中,都交给DI就行。
2、DI(Dependency Injection)即依赖注入,可以说是IoC的其中一个内容,在容器实例化对象的时候主动的将被调用者(或者说它的依赖对象)注入给调用对象。也可以理解为:应用程序在运行时依赖IoC容器来动态注入对象需要的外部资源
。
3、对象可以通过构造函数参数、工厂方法的参数或从工厂方法构造或返回对象实例后在其上设置属性来定义其依赖(要使用)的其他对象。随后,IoC容器在创建Bean时会自动注入这个Bean的依赖项。这个过程基本上和Bean主动通过类的构造器和setter方法来设置其依赖项的过程是相反的,因此DI也称为控制反转(Inversion of Control、IoC)
。
4、常用的注入方式主要有三种:
构造方法注入(Construct注入) 基于注解的注入(接口注入)
2、构造方法注入
1、构造器依赖注入是由IoC容器调用带有许多参数的构造器来完成的,每个参数表示一个依赖项。
2、使用构造器依赖注入方式,需要依赖<bean />
标签的子标签<constructor-arg />
,一个<constructor-arg />
标签表示一个属性。
3、<constructor-arg />
标签参数介绍:<constructor-arg value="" index="" name="" ref="" type="" />
属性 说明 value
设置参数列表参数对应的值,用于设定基本数据类型和String类型
的数据 index
通过参数在参数列表中的索引找到参数列表中对应参数,index从0开始 name
通过参数名找到参数列表中对应参数 ref
如果参数值为非基本数据类型,则可通过ref为参数注入值,其值为另一个bean标签id或name属性的属性值 type
通过参数数据类型找到参数列表中对应参数
public class Subject {
private String name;
private String teacher;
public Subject ( String name, String teacher) {
this . name = name;
this . teacher = teacher;
System . out. println ( "构造器依赖注入" ) ;
}
@Override
public String toString ( ) {
return "Subject{" +
"科目='" + name + '\'' +
", 老师='" + teacher + '\'' +
'}' ;
}
}
<?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 = " subject" class = " com.itan.beans.Subject" >
< constructor-arg value = " Java" />
< constructor-arg value = " 张三" />
</ bean>
</ beans>
public class Test4 {
public static void main ( String [ ] args) {
ApplicationContext context = new ClassPathXmlApplicationContext ( "spring-config.xml" ) ;
Subject bean = context. getBean ( Subject . class ) ;
System . out. println ( bean) ;
}
}
3、setter方法注入
1、setter依赖注入是由IoC容器调用参数的setter方法完成,setter方法是在调用构造器以实例化bean之后完成的。
2、setter方法实际上就是常说的get、set方法中的set方法,因此在使用setter注入的时候需要提供setXXX方法
,这个XXX一般就是表示属性名,方法名应该按照Java方法名的规定来定义,属性的第一个字母大写,通常我们可以使用idea来自动生成set方法。
3、使用setter方法注入方式,需要依赖<bean />
标签的子标签<property />
,一个<property />
标签表示一个setter方法。
4、<property />
标签参数介绍:<property name="" value="" ref="" />
属性 说明 name
属性名称 value
设置属性对应的值 ref
如果参数值为非基本数据类型,则可通过ref为参数注入值,其值为另一个bean标签id或name属性的属性值
public class Teacher {
private String name;
private int age;
public void setName ( String name) {
System . out. println ( "setter属性注入name" ) ;
this . name = name;
}
public void setAge ( int age) {
System . out. println ( "setter属性注入age" ) ;
this . age = age;
}
@Override
public String toString ( ) {
return "Teacher{" +
"姓名='" + name + '\'' +
", 年龄=" + age +
'}' ;
}
}
<?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 = " teacher" class = " com.itan.beans.Teacher" >
< property name = " name" value = " 张三" />
< property name = " age" value = " 25" />
</ bean>
</ beans>
public class Test4 {
public static void main ( String [ ] args) {
ApplicationContext context = new ClassPathXmlApplicationContext ( "spring-config.xml" ) ;
Teacher teacher = context. getBean ( Teacher . class ) ;
System . out. println ( teacher) ;
}
}