Spring知识体系
一、基本介绍
1.Spring全家桶:
Spring、SpringMVC、Spring Boot、Spring Cloud
其中Spring是其他的基础。
2.Spring:
出现的目的是为了解决企业级开发的难度。减轻对项目模块之间的管理,类和类之间的管理,帮助开发人员创建对象,管理对象之间的关系。
3.核心技术:
IOC、AOP:实现模块之间,类之间的解耦合。
4.依赖概念:
类A使用了类B属性或方法、称A依赖于B。
二、Spring优点
1.使用Spring的IOC容器,将对象之间的依赖关系交给Spring,降低组件之间的耦合性,让我们更专注于应用逻辑
2.可以提供众多服务,事务管理,WS等。
3.AOP的很好支持,方便面向切面编程。
4.对主流的框架提供了很好的集成支持,如Hibernate,Struts2,JPA等
5.Spring DI(也即使IOC:反转控制)机制降低了业务对象替换的复杂性。
6.Spring属于低侵入,代码污染极低。
7.Spring的高度可开放性,并不强制依赖于Spring,开发者可以自由选择Spring部分或全部
补充:
框架是一个软件,是其他人写好的软件。
1.知道框架能做什么:如mybatis > 访问数据库,对表中的数据实现增删改查。
2.框架的语法格式:框架要完成一个功能,是需要一定步骤支持的。
3.框架的内部实现:框架内部怎么做,原理是什么。(提升)
4.通过学习,可以实现一个框架。(方向)
三、核心功能一:IOC(控制反转)
基于XML的DI:
1、相关概念:
①.IOC:是一个理论,概念,思想。描述的是把对象的创建,赋值,管理工作都交给代码之外的容器去实现。对象的创建是由其他外部资源完成。
②.控制:创建对象,对象的属性赋值,对象之间的关系管理。
③.正转:由开发人员在代码中,使用new构造方法创建对象,开发人员主动管理对象。
④.反转:把原来开发人员的管理,创建对象的权限转移给代码之外的容器实现,由容器代替开发人员管理对象,创建对象,给属性赋值。
⑤.容器:可以是一个服务器软件,也可以是一个框架。
⑥.为什么要使用IOC呢:目的是减少对代码的改动,也能实现不同的功能。实现解耦合。
2、IOC的技术实现:
①.DI(Dependency Injection 依赖注入)是IOC的技术实现。
我们只需要在程序中提供要使用的对象的名称,至于对象如何在容器中创建,赋值,查找都有容器在内部实现。
Spring是使用的DI实现IOC的功能,Spring底层创建对象,使用的是反射机制。
②.创建过程:
1.创建Maven
2.导入依赖
3.创建类(接口和他的实现类)就是普通类
4.创建Spring需要使用的配置文件 在文件中声明配置信息。这些类由Spring创建和管理。
代码如下:
<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">
<!--
告诉Spring创建对象
声明bean,就是告诉Spring要创建某个类的对象
id:对象的自定义名称,唯一值。 Spring通过这个名称去找到对象
class:是类的全限定名称(不能是接口,因为Spring是反射机制)
-->
<!-- Spring完成类创建之后,把创建好的对象放进Map中存储起来-->
<!-- 一个bean标签声明一个对象 -->
<bean id="someService" class="com.tjse.service.Impl.SomeServiceImpl"></bean>
</beans>
<!--
Spring配置文件
beans是根标签,Spring把java对象称为bean
spring-beans.xsd是约束文件,和mybatis里面dtd一致。xsd约束效果更强
-->
// 测试类中使用Spring创建bean对象
// 1.创建Spring容器对象,加载Spring配置信息
ApplicationContext ac = new ClassPathXmlApplicationContext("Spring.xml");
// 2.从容器中获取需要的对象 (需要的某个对象进行强转)
SomeService someService = (SomeService) ac.getBean("someService");
// 3.正常调用方法
someService.dosome();
补充:
①.Spring默认创建对象的时间:在创建Spring容器时。
②.使用Spring提供的方法,获取容器中定义的对象数量
.getBeanDefinitionCount();
③.获取容器中每个定义对象的名称
.getBeanDefinitionNames();
3.设值注入:
Spring配置文件中,给java对象的属性赋值
DI:依赖注入,表示创建对象,给属性赋值
实现语法有两种:
1.基于XML的DI实现
2.基于注解DI实现.
DI的语法分类:
1.set注入:Spring调用类的set方法,在set方法可以实现属性的赋值
2.构造注入:Spring调用类的有参构造方法,创建对象,在构造方法中完成赋值.
注入:就是赋值的意思。
简 单类型:Spring中规定java的基本数据类型和String都是简单类型
简单类型注入如下:
<bean id="" class="">
<property name"属性名" value="属性值">
</bean>
引用类型的set注入如下:
<bean id="" class="">
<property name="属性名称" ref="bean对象id(对象的名称)"></property>
</bean>
补充:这时,我们不用管类是否是自己书写,若想进行赋值操作,那么只需看类里面是否存在set方式(唯一标准)。
构造注入如下:
构造注入使用的是<constructor-arg>标签
其中属性分别为:
name:表示构造方法的形参名
index:表示构造方法的参数位置,参数从左往右的位置是0,1,2的顺序
value:简单类型参数值
ref:引用类型参数值
4.自动注入:
引用类型的自动注入:Spring框架根据某些规则可以给引用类型进行赋值。(简单类型无效)
不用你再给引用类型赋值。
使用的规则常用byName、byType。
1.byName(按名称注入):java类中引用类型的属性名和Spring容器中(配置文件)
<bean>的ID名称一样,且数据类型是一致的,这样的容器中的bean,Spring能够赋值给引用类型.
语法如下:
<bean id="" class="" autowire="byName">
简单类型属性赋值
</bean>
代替引用类型,加快开发效率。
2.byType(按类型注入):java类中引用类型的数据类型和Spring容器中(配置文件)
<bean>的class属性是同源关系的,这样的bean能够赋值给引用类型。
同源就是一类意思:
1.java类中引用的类型的数据类型和bean的class的值是一样的
2.java类中引用的类型的数据类型和bean的class的值父子类关系的
3.java类中引用的类型的数据类型和bean的class的值接口和实现类关系的。
语法如下:
<bean id="" class="" autowire="byType">
简单类型属性赋值
</bean>
注意说明:在byType,在xml配置文件中声明bean只能有一个符合条件的,多余一个是错误的。
5.多配置文件:
优点:
1.每个文件大小比一个文件要小很多,效率高,避免多人操作带来的冲突。
多文件的分配方式:
1.按功能模块,一个模块一个配置文件。
2.按类的功能,数据库相关的配置一个配置文件,做事务的功能一个配置文件,做service功能的一个配置文件等。
<!--
Spring-total表示主配置文件:包含其他的配置文件的,主配置文件一般不定义对象的。
语法:<import resource="其他配置文件的路径"/>
在包含关系的配置文件中,可以是通配符。(*)
使用时注意不要写成死循环。(总文件名包含在通配符识别文件中)
-->
<import resource="classpath:"></import>
基于注解DI:
通过注解完成java对象创建,属性赋值。
1.使用注解的步骤:
①加入maven的依赖Spring-context,在你加入spring-context的同时。简介加入spring-aop的依赖。使用注解必须使用spring-aop依赖。
②在类中加入Spring的注解(多个不同功能的注解)
③在Spring的配置文件中,加入一个组件扫描器的标签,说明注解在你的项目中的位置。
④创建容器,使用类
2.需要学习的注解:
① @Component:组成部分,组件。
类中:
@Component:创建对象的,等同于<bean>的功能
属性:value就是对象的名称,也就是bean的id值
value的值是唯一的,创建的对象在整个Spring容器中就一个
@Component(value = "myxxx")
也可以
@Component("myxxx"):省略value
或
@Component :不指定对象名称,有Spring默认提供:类名的首字母小写
配置文件中:
<!-- 声明组件扫描器 component-scan -->
<context:component-scan base-package="类所在的包名"></context:component-scan>
② @Repository:仓库,知识库
用在持久层类上面
放在dao的实现类上面,表示创建dao对象,dao对象是能访问数据库数据。
③ @Service
用在业务层类的上面
放在service的实现类上面,创建service对象,service对象是做业务处理的。可以有事务功能的。
④ @Controller
用在控制器上面的
放在控制器(处理器)类的上面,控制器对象,能够接收用户提交的参数,显示请求处理结果。
以上三个注解语法和@Component一样的,都能创建对象,但是三个注解还有额外功能
主要用于给项目对象分层。
⑤ @Value
简单类型的属性赋值
属性: value 是String类型的,表示简单类型的属性值
位置:1.在属性定义的上面,无需set方法,推荐使用。
2.在set方法上面
⑥ @Autowired
引用类型的赋值:自动注入原理,支持byName,byType
1.默认使用byType
位置:在属性定义上面,无需set方法,推荐使用
2.使用byName
需要在@Autowired 下面加入@Qualifier(value = “bean的id”)
练习:使用注解方式 实现创建对象 对属性(包括引用类型)进行赋值
1.遇到问题:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘java.lang.String’ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
2.问题分析
可以看到提示显示的是没有找到NoSuchBeanDefinition 原因是springioc容器加载bean默认使用无参构造进行初始化。
而Spring实例化bean有四种方式
1.无参构造方法实例化(Spring默认,常用,需要bean类中存在无参构造方法);
2.静态工厂实例化
3.实例化工厂实例化
4.注解方式实例化+
3.问题解决
加一个默认的构造方法就可以了。
⑦ @Resource
来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值,使用的也是自动注入远,支持byName,byType 默认是byName。
位置:在属性定义的上面,无需set方法 推荐使用。
处理过程:先使用byName,如果失败,则继续使用byType。
两种DI方法区别:
更改代码较多:xml
整体便捷明了:注解
四、核心功能二:AOP(面向切面编程)
AOP(Aspect Orient Programming),面向切面编程。面向切面编程是从动态角度考虑程 序运行过程。 AOP 底层,就是采用动态代理模式实现的。采用了两种代理:JDK 的动态代理,与 CGLIB 的动态代理。让开发人员用一种统一的方式,就用动态代理。
Aspect:切面。给你的目标类增加的功能, 一般都是非业务方法。
Orient :面向
Programming:编程
如何理解:
①:需要分析项目功能时,找出切面
②:合理的安排切面的执行时间(在目标方法前,还是目标方法后)
③:合理的安排切面的执行位置。
通过动态代理引入AOP
1.jdk动态代理实现步骤:
①创建目标类,someServiceImpl目标类,给它的dosome,doother增加输出时间,事务
②创建InvocationHandler接口的实现类,在这个类实现给目标方法增加功能。
③使用jdk中 类Proxy,创建代理对象。实现创建对象的能力。
术语:
Aspect:切面。给你的目标类增加的功能, 一般都是非业务方法。常见的切面功能有日志,事务,统计信息,参数检查,权限验证。
JoinPoint:连接点,连接业务方法和切面的 位置,就某类中的业务方法。
Pointcut:切入点,指多个连接点方法的集合。
目标对象:给哪个类的方法增加功能,这个类就是目标对象
Advice:通知,通知表示切面功能执行的时间。
AOP的实现:
aop是一个规范,是动态代理的规范化,一个标准。
aop的技术实现框架:
1.spring:spring的内部实现了aop规范,能做aop的工作。
spring主要在事务处理使用aop。项目开发中很少使用aop 比较笨重。
2.aspectJ:一个开源的专门做aop的框架。spring框架集成了aspectJ框架
通过spring就能使用aspectJ的功能。aspectJ框架实现aop两种方式。
一种使用xml的配置文件:配置全局事务。
在项目中实现aop功能,一般都使用注解,aspectj有5个注解。
aspectJ的框架使用:
1.切面的执行时间,这个执行时间在规范中叫做Advice(通知,增强)
在aspectJ框架中使用注解表示的。
@Before
@AfterReturning
@Around
@AfterThrowing
@After
2.表示切面执行的位置,使用的是切入点表达式。
必须写: execution(方法返回值 方法声明(参数))
aspectJ实现aop的基本步骤:
1.新建maven项目
2.加入依赖
①spring依赖
②aspectJ依赖
③junit单元测试
3.创建目标类:接口和实现类 要做的事给类中的方法添加功能
4.创建切面类:普通类
①在类的上面加入@Aspect
②在类中定义方法,方法就是切面要执行的功能代码,在方法的上面加入aspectj的通知注解,例如@Before 还需要指定切入点表达式execution()
5.创建Spring的配置文件:声明对象,要把对象交给容器统一管理。
①声明目标对象
②声明切面类对象
③声明aspectJ框架中的自动代理生成器标签。 它是用来完成代理对象的自动创建功能的。
- 创建测试类,从spring容器中获取目标对象(实际上就是代理对象) 通过代理执行方法,实现aop的功能增强。
未完 待后续更新。