Spring
Spring概念
Spring有哪些主要模块
Spring框架至今已经集成了20多个模块。主要是核心容器、数据访问/集成、Web、AOP、工具、消息和测试模块。
spring框架概述
1.spring是一个轻量级的、开源的J2EE框架
轻量级:扎包数量少,体积小,可独立提供使用。
开源:免费提供源代码。
框架:开发更方便,代码更简洁。
2.解决企业应用开发的复杂性
3.两个核心部分:IOC,AOP。
IOC : 控制反转,把创建对象的过程交给spring管理。
AOP : 面向切面,不修改源代码进行功能增强。
4.特点
- 方便解耦,简化开发
- AOP编程支持
- 方便程序测试
- 方便和其他框架集成
- 方便进行事务操作
- 降低API使用难度
Spring Framework 有哪些不同的功能
- 轻量级 - Spring 在代码量和透明度方面都很轻便。
- IOC - 控制反转实现了松散耦合。
- AOP - 面向切面编程,可以将应用业务逻辑和系统服务分离,以实现高内聚。
- 容器 - Spring 负责创建和管理对象(Bean)的生命周期和配置。
- MVC - 对 web 应用提供了高度可配置性,其他框架的集成也十分方便。
- 事务管理 - 提供了用于事务管理的通用抽象层。Spring 的事务支持也可用于容器较少的环境。
- JDBC 异常 - Spring 的 JDBC 抽象层提供了一个异常层次结构,简化了错误处理策略。
什么是 Spring 配置文件?
Spring 配置文件是 XML 文件。该文件主要包含类信息。它描述了这些类是如何配置以及相互引入的。但是,XML 配置文件冗长且更加干净。如果没有正确规划和编写,那么在大项目中管理变得非常困难。
Spring 应用程序有哪些不同组件?
Spring 应用一般有以下组件:
接口 - 定义功能。
Bean 类 - 它包含属性,setter 和 getter 方法,函数等。
Spring 面向切面编程(AOP) - 提供面向切面编程的功能。
Bean 配置文件 - 包含类的信息以及如何配置它们。
用户程序 - 它使用接口。
使用 Spring 有哪些方式?
作为一个成熟的 Spring Web 应用程序。
作为第三方 Web 框架,使用 Spring Frameworks 中间层。
用于远程使用。
作为企业级 Java Bean,它可以包装现有的 POJO(Plain Old Java Objects)。
配置对象创建
1.配置对象创建
<bean id="id名字" class="类全路径:包+类"></bean>
2.加载spring配置文件
ApplicationContext context=new ClassPathXmlApplicationContext(.xml);
3.获取配置创建的对象
类名 实例化=context.getBean("id名字",类名.class);
IOC容器
IOC相关概念
什么是IOC
1.控制反转,把对象的创建和对象之间的调用过程,交给spring进行管理。
2.使用目的:降低耦合度
IoC 的一些好处是:
它将最小化应用程序中的代码量。
它将使您的应用程序易于测试,因为它不需要单元测试用例中的任何单例或 JNDI 查找机制。
它以最小的影响和最少的侵入机制促进松耦合。
它支持即时的实例化和延迟加载服务。
什么是Spring IOC容器
Spring IOC负责创建对象、管理对象(通过依赖注入(DI)、装配对象、配置对象,并且管理这些对象的整个生命周期。
什么是依赖注入?
- DI: Dependency Injection(依赖注入)的简写。
- 不必创建对象,但必须描述如何创建它们。
- 不是直接在代码中将组件和服务连接在一起,而是描述配置文件中哪些组件需要哪些服务。
- 由 IOC 容器将它们装配在一起,相当于把每个bean和bean之间的关系交给Spring IOC容器来管理。
IOC和DI的关系?
控制反转(IOC)和依赖注入(DI)是从不同角度描述同一件事情,利用依赖关系注入的方式,实现对像之间的解耦。
IOC底层原理\实现机制
1.xml解析、工程模式、反射机制。
IOC过程
进一步降低耦合度
IOC容器有哪些
- IOC思想基于IOC容器,IOC容器底层就是对象工厂。
- Spring提供IOC容器实现两种方式:
- BeanFactory:IOC容器最基本实现方式,是spring内部使用的接口,不提供给开发人员
加载配置文件时不会创建对象,在获取对象时在创建
- ApplicationContext:是BeanFactory子接口,提供更多更强大的功能,一般提供给开发人员
加载配置文件时创建对象
- BeanFactory子接口
ConfigurableApplicationContext:相关扩展功能
- ApplicationContext接口有实现类
FileSystemXmlApplicationContext
ClassPathXmlApplicationContext
BeanFactory 和 ApplicationContext区别
IOC操作Bean管理
什么是 spring bean?
它们是构成用户应用程序主干的对象。
Bean 由 Spring IoC 容器管理。
它们由 Spring IoC 容器实例化,配置,装配和管理。
Bean 是基于用户提供给容器的配置元数据创建。
什么是Bean管理
1.Spring创建对象
2.Spring属性注入
Spring中的bean是线程安全的吗
Spring容器中的Bean是否线程安全,容器本身并没有提供Bean的线程安全策略,因此可以说spring容器中的Bean本身不具备线程安全的特性,但是还是要结合具体的scope的Bean去研究。
Spring创建对象有哪几种方式
①无参构造
②有参构造
③静态工厂模式(1个bean标签)
④非静态工厂模式(2个bean标签)
//1.无参构造
<bean id="user" class="com.wpq.pojo.User"></bean>
//在bean标签内部使用property标签,相当于调用set方法. name:要赋值的属性的属性名 value:值
<bean id="user" class="com.wpq.pojo.User">
<property name="name" value="zs"></property>
<property name="password" value="123"></property>
</bean>
//2.有参构造
<bean id="user" class="com.wpq.pojo.User">
<constructor-arg index="0" type="java.lang.String" name="name" value="张三"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" name="password" value="123"></constructor-arg>
</bean>
//3.静态工厂模式--createPerson()为静态方法
<bean name="personFactory" class="com.wpq.factory.PersonFactory" factory-method="createPerson"/>
//4.工厂模式
<!--1.创建出工厂对象-->
<bean name="personFactory" class="com.wpq.factory.PersonFactory"/>
<!--2.调用工厂的instancePerson()方法创建出Person对象-->
<bean name="person" factory-bean="personFactory" factory-method="instancePerson"/>
依赖注入DI的方式有几种
①set方法注入
②构造函数注入
③P命名空间注入
④spel表达式注入
⑤复杂类型(集合)注入
①set方法注入
在bean标签内部使用property标签,相当于调用set方法
<bean id="user" class="com.wpq.pojo.User">
<property name="name" value="zs"></property>
<property name="password" value="123"></property>
</bean>
②构造函数注入
在bean标签内部使用constructor-arg标签,相当于构造函数注入
<bean id="user" class="com.wpq.pojo.User">
<constructor-arg index="0" type="java.lang.String" name="name" value="张三"></constructor-arg>
<constructor-arg index="1" type="java.lang.String" name="password" value="123"></constructor-arg>
</bean>
③P命名空间注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--第3种注入方式:p命名空间,记得引入一个命名空间字符串:xmlns:p="http://www.springframework.org/schema/p"-->
<!--p:property的缩写!简化了set方式注入的代码编写-->
<bean name="car" class="com.wpq.domain.Car" p:logo="马车" p:color="黑色"/>
<bean name="person" class="com.wpq.domain.Person" p:name="阮小二" p:age="40" p:car-ref="car"/>
</beans>
构造函数注入和 setter 注入 区别
FactoryBean
spring有两种类型bean:Bean,FactoryBean。
- Bean:在配置文件中定义的bean类型就是返回类型
- FactoryBean:在配置文件中定义的bean类型可以和返回值不一样
第一步:创建类,让这个类作为工厂bean,实现接口FactoryBean
第二步:实现接口中方法,在实现的方法中定义返回的bean类型
Bean作用域
① singleton 单例模式 (Scope默认):@Scope(value = “singleton”)
② prototype 多例模式:每次获取Bean的时候会有一个新的实例
③ request: request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
④ session:该作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
⑤ global session:该作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个 portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。如果你在web中使用global session作用域来标识bean,那么web会自动当成session类型来使用。
1.设置bean是单实例还是多实例(.默认情况是单实例)
单实例
2.通过bean标签中scope属性设置单实例或多实例
- scope:
1.singlton:默认单实例
2.prototype:多实例
3.request:请求
4.session:
singlton单实例与prototype多实例区别:
1.创建时机
singlton:加载文件时创建对象
prototype:在getBean时创建
Bean生命周期
生命周期:从对象的创建到销毁的过程
1.通过构造器创建(无参构造)
2.为属性设置值和其他bean引用(set方法)
3.调用bean初始化方法(配置)
4.可使用(对象获取到)
5.当容器关闭时,调用bean销毁方法(需要配置销毁方法)
bean的后置处理器,bean的生命周期
3之前:把bean实例对象传给bean后置处理器 postProcessBeforeInitialization
3之后:把bean实例对象传给bean后置处理器postProcessAfterInitialization
1.创建类 ,实现接口BeanPostProcessor,创建后置处理器
2.配置文件配置
什么是 spring 的内部 bean?
只有将 bean 用作另一个 bean 的属性时,才能将 bean 声明为内部 bean。
什么是 spring 装配
当 bean 在 Spring 容器中组合在一起时,它被称为装配或 bean 装配。 Spring 容器需要知道需要什么 bean 以及容器应该如何使用依赖注入来将 bean 绑定在一起,同时装配 bean。
自动装配有哪些方式?
Spring 容器能够自动装配 bean。也就是说,可以通过检查 BeanFactory 的内容让 Spring 自动解析 bean 的协作者。
自动装配的不同模式:
no - 默认设置,表示没有自动装配。应使用显式 bean 引用进行装配。
byName - 根据 bean 的名称注入对象依赖项。匹配并装配其属性与 XML 文件中由相同名称定义的 bean。
byType - 根据类型注入对象依赖项。如果属性的类型与 XML 文件中的一个 bean 名称匹配,则匹配并装配属性。
构造函数 - 它通过调用类的构造函数来注入依赖项。它有大量的参数。
autodetect - 首先容器尝试通过构造函数使用 autowire 装配,如果不能,则尝试通过 byType 自动装配。
自动装配有什么局限?
- 覆盖的可能性 - 您始终可以使用 和 设置指定依赖项,这将覆盖自动装配。
- 基本元数据类型 - 简单属性(如原数据类型,字符串和类)无法自动装配。
- 令人困惑的性质 - 总是喜欢使用明确的装配,因为自动装配不太精确。
spring 提供了哪些配置方式
1.基于xml配置
2.基于注解配置
3.基于java API配置
1.基于xml配置
bean 所需的依赖项和服务在 XML 格式的配置文件中指定。这些配置文件通常包含许多 bean 定义和特定于应用程序的配置选项。它们通常以 bean 标签开头。
<bean id="studentbean" class="org.edureka.firstSpring.StudentBean">
<property name="name" value="Edureka"></property>
</bean>
2.基于注解配置
可以通过在相关的类,方法或字段声明上使用注解,将 bean 配置为组件类本身。默认情况下,Spring 容器中未打开注解装配。因此,需要在使用它之前在 Spring 配置文件中启用它。
<beans>
<context:annotation-config/>
<!-- bean definitions go here -->
</beans>
3.基于java API配置
@Bean 和 @Configuration 来实现。
@Bean 注解扮演与 元素相同的角色。
@Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。
@Configuration
public class StudentConfig {
@Bean
public StudentBean myStudent() {
return new StudentBean();
}
}
基于xml
1.基于xml创建对象
在spring配置文件中,使用bean标签,并添加属性
① id (唯一标识)
② name(获取bean的键)
③ class(指定bean对应类的全路径)
④ scope(单例或者多例设计模式)
⑤ lazy-init(延时加载,默认值:false):设置false时,只有调用getBean方法才会创建对象
⑥ init-method(指定:监听对象创建的方法)
⑦ destroy-method(指定:监听对象销毁的方法)
创建对象,默认执行无参构造方法。
2.基于xml注入属性
DI : 依赖注入,就是注入属性
1.set方法注入
- 创建一个类,定义属性和set方法
- 在spring配置文件中配置对象创建和属性注入
2.有参构造函数
- 创建类,定义属性,创建有参构造方法
- 有参注入
3.p名称空间注入
可简化基于xml注入
第一步 添加p名称空间在配置文件中
第二步 进行属性注入,在bean标签中进行操作
xml注入其他属性
1.字面量(属性的固定值)
(1)null值
(2)包含特殊符号
2.注入属性-外部bean
(1)创建service类和dao类
(2)在service类中调用dao中方法
(3)在spring配置文件中配置
3.注入属性-内部bean
什么是 spring 的内部 bean?
只有将 bean 用作另一个 bean 的属性时,才能将 bean 声明为内部 bean。
(1)一对多关系:一个部门中多个员工
(2)在实体类之间表示一对多关系
(3)在spring配置文件中配置
4.注入属性-级联赋值
第一种:
第二种
5.注入属性-注入集合属性
1.数组属性
2.List集合属性
3.注入Map属性
(1)创建类定义属性,生成set方法
(2)在spring配置文件中
4.在集合里面设置对象类型值
5.把集合注入部分提取出
(1)在spring配置文件中引入util
xml自动装配
根据指定装配规则(属性名称或属性类型),spring自动将匹配的属性值进行注入。
外部属性文件
1.直接配置数据库信息
(1)配置德鲁伊连接池
2.引入外部属性文件配置数据库连接池
(1)创建外部属性文件,properties格式文件,写数据库信息
(2)把外部属性properties文件引入spring配置文件中
基于注解
什么是注解
注解:是代码里特殊的标记,格式:@注解名称(属性名称=属性值…)
使用方法:作用在类、方法、属性上。
目的:简化xml配置
Spring针对Bean管理中创建对象提供注解
1.@Component
2.@Service
3.@Controller
4.@Repository
功能一样
什么是基于注解的容器配置
不使用 XML 来描述 bean 装配,开发人员通过在相关的类,方法或字段声明上使用注解将配置移动到组件类本身。它可以作为 XML 设置的替代方案。
Spring 的 Java 配置是通过使用 @Bean 和 @Configuration 来实现。
- @Bean 注解扮演与 元素相同的角色。
- @Configuration 类允许通过简单地调用同一个类中的其他 @Bean 方法来定义 bean 间依赖关系。
@Configuration
public class StudentConfig {
@Bean
public StudentBean myStudent() {
return new StudentBean();
}
}
如何在 spring 中启动注解装配?
默认情况下,Spring 容器中未打开注解装配。因此,要使用基于注解装配,我们必须通过配置
<context:annotation-config /> 元素在 Spring 配置文件中启用它。
有哪些注解?分别表示什么含义?
①注解实现IOC
- @Component:组件注解,用来创建一个对象,等同于在xml中写了bean标签。
②注解实现DI
- @Value(“…”): 只能给简单类型注入值,不能给引用类型注入值,使用在成员变量上或set方法上 (简单类型=String+8种基本类型)
注意:该注解可以引入配置文件中的变量。 语法: @Value(“${age}”)- @Autowired: 自动装载对象,默认情况下是按照类型来进行匹配。
- @Qualifier: 该注解一般要结合@Autowired的一起使用,当@Autowired根据类型无法匹配对象的时候,进行辅助,根据名称进行依赖注入.解决无法根据类型进行唯一性对象匹配的问题.
- @Resource: 等同于@Autowired+@Qualifier,该注解是Java原生的注解,既可以根据类型,又可以根据名称进行依赖注入.
③ Bean标签的属性对应的注解
作用域: @Scope(scopeName=“单例/多例”)
延迟加载:@Lazy: 等同于中的lazy-init属性 ,设置是否延迟加载
创建对象监听:@PostConstruct 指定监听对象创建的方法
销毁对象监听:@PreDestroy 指定监听对象销毁的方法
④ 组件注解
@Component:组件注解
@Controller:组件注解,一般用于web层对象的创建
@Service:组件注解,一般用于service层对象的创建
@Repository:组件注解,一般用于dao层对象的创建
⑤ 测试注解
@RunWith(SpringJUnit4ClassRunner.class) :括号内指定完成测试工作的类
@ContextConfiguration(“classpath:appication-Collection.xml”) : 指定要加载的XML配置文件
@Test :写在测试方法上
⑥ 元注解
@Target(ElementType.FIELD):定义注解的作用范围
@Retention(RetentionPolicy.RUNTIME):定义注解的生命周期(保留策略)
自定义注解:必须带上面两个元注解
@Component, @Controller, @Repository, @Service 有何区别
- @Component:将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中。
- @Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。
- @Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图。
- @Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。
@Required 注解有什么用?
@Required 应用于 bean 属性 setter 方法。此注解仅指示必须在配置时使用 bean 定义中的显式属性值或使用自动装配填充受影响的 bean 属性。如果尚未填充受影响的 bean 属性,则容器将抛出 BeanInitializationException。
public class Employee {
private String name;
@Required
public void setName(String name){
this.name=name;
}
public string getName(){
return name;
}
}
@Autowired 注解有什么用?
@Autowired 可以更准确地控制应该在何处以及如何进行自动装配。此注解用于在 setter 方法,构造函数,具有任意名称或多个参数的属性或方法上自动装配 bean。默认情况下,它是类型驱动的注入。
public class Employee {
private String name;
@Autowired
public void setName(String name) {
this.name=name;
}
public string getName(){
return name;
}
}
@Qualifier 注解有什么用?
当创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,您可以使用@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义。
例如,这里我们分别有两个类,Employee 和 EmpAccount。在 EmpAccount 中,使用@Qualifier 指定了必须装配 id 为 emp1 的 bean。
EmpAccount.java
public class EmpAccount {
private Employee emp;
@Autowired
@Qualifier(emp1)
public void showName() {
System.out.println(“Employee name : ”+emp.getName);
}
}
@RequestMapping 注解有什么用?
@RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:
类级别:映射请求的 URL
方法级别:映射 URL 以及 HTTP 请求方法
注解实现IOC和DI的准备工作有哪些
① 在XML文件中引入Context的约束
② 配置组件扫描器
③使用注解
第一步:引入AOP依赖
第二步:开启组件扫描
第三步:创建类 ,在类上面添加创建对象注解
开启组件扫描注意点
1.设置哪些扫描2.设置哪些不扫描
属性注入
1.@Aitowired:根据属性类型注入
第一步:把service和dao对象创建,在七类添加创建对象的注解
第二步:在service对象注入
2.@Qualifier:根据属性名称进行注入
和@Autowired一起使用
3.@Resource:属性类型、名称
4.@Value:注入普通属性类型
完全注解开发
1.创建配置类,代替xml配置文件
2.测试类
AOP
概念
什么是AOP(Aspect Oriented Programming)
- 面向切面编程,利用AOP可以对业务逻辑进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
- 不通过修改源代码方式添加新功能
AOP 有哪些实现方式?
实现 AOP 的技术,主要分为两大类:
- 静态代理 - 指使用 AOP 框架提供的命令进行编译,从而在编译阶段就可生成 AOP 代理类,因此也称为编译时增强;
编译时编织(特殊编译器实现)
类加载时编织(特殊的类加载器实现)。- 动态代理 - 在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
JDK 动态代理
CGLIB
Spring AOP and AspectJ AOP 有什么区别?
Spring AOP 基于动态代理方式实现;AspectJ 基于静态代理方式实现。
Spring AOP 仅支持方法级别的 PointCut;AspectJ 提供了完全的 AOP 支持,它还支持属性级别的 PointCut。
如何理解 Spring 中的代理?
将 Advice 应用于目标对象后创建的对象称为代理。在客户端对象的情况下,目标对象和代理对象是相同的。
什么是编织(Weaving)?
为了创建一个 advice 对象而链接一个 aspect 和其它应用类型或对象,称为编织(Weaving)。在 Spring AOP 中,编织在运行时执行。请参考下图:
AOP底层原理
AOP底层使用了动态代理 - 在运行时在内存中“临时”生成 AOP 动态代理类,因此也被称为运行时增强。
- 有接口情况,使用JDK动态代理
- 无接口情况,使用CGLIB动态代理
1.有接口
创建接口类实现类代理对象,增强类的方法
2.无接口
创建子类的代理对象
JDK动态代理
使用Proxy类里的方法创建代理对象
1.newProxyInstance
第一个参数:类加载器;
第二个参数:增强方法所在类,这个类实现的接口,支持多个接口
第三个参数:实现这个接口InvocationHandler,创建代理对象,写增强方法
1.创建接口
2.创建实现类
3.使用proxy类创建代理对象,增强类方法
AOP术语
1.连接点:类里面哪些方法可以被增强
2.切入点(JoinPoint):实际被增强的方法
什么是 Aspect?
aspect 由 pointcount 和 advice 组成, 它既包含了横切逻辑的定义, 也包括了连接点的定义. Spring AOP 就是负责实施切面的框架, 它将切面所定义的横切逻辑编织到切面所指定的连接点中.
AOP 的工作重心在于如何将增强编织目标对象的连接点上, 这里包含两个工作:
- 如何通过 pointcut 和 advice 定位到特定的 joinpoint 上
- 如何在 advice 中编写切面代码.
可以简单地认为, 使用 @Aspect 注解的类就是切面.
什么是通知(Advice)?
特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice。Spring AOP 使用一个 Advice 作为拦截器,在 JoinPoint “周围”维护一系列的拦截器。
XML方式实现AOP的通知有几种
通知(增强):实际增强的逻辑部分
1.前置通知: before
2.后置通知:after-Returning
3.环绕通知:around
4.异常通知:after-Throwing
5.最终通知:after
4.切面:是动作,把通知应用到切入点
AOP操作(准备)
spring框架一般基于AspectJ实现AOP操作
- AspectJ:独立的框架,为了方便和spring框架一起使用
基于AspectJ实现AOP操作
- 基于XML配置文件实现
- 基于注解方式实现(使用)
引入AOP相关依赖
切入点表达式
1.切入点表达式作用:知道对哪个类哪个方法进行增强
2.语法结构:
execution( [ 权限修饰符 ] [ 返回类型 ] [类全路径] [ 方法名称 ] ( [ 参数列表 ] ) )
例1:对com.atguigu.dao.BookDao类里面的add进行增强
execution(com.atguigu.dao.BookDao.add(…))
例2:对com.atguigu.dao.BookDao类里面所有方法进行增强
execution(com.atguigu.dao.BookDao.(…))
例2:对com.atguigu.dao包里面所有类和方法进行增强
execution( com.atguigu.dao..(…))
AOP(AspectJ注解)
1.创建类,在类里定义方法
2.创建增强类
在增强类中,创建方法,让不同方法代表不同通知
3.进行通知的配置
在spring文件中,开启注解扫描
使用注解创建对象
在增强类上添加注解@Aspect
在spring配置文件中开启生成代理对象
4.配置不同类型通知
(1)在增强类中,作为通知方法上添加通知类型注解,使用切入点表达式配置
5.公共切入点抽取
6.多个增强类对一个类增强,设置增强优先级
(1) 在增强类加注解@Order(数字),数字越小优先级越高
注解实现AOP的过程
1.配置Spring XML文件
开启自动代理 <aop:aspectj-autoproxy/> :声明自动为spring容器中那些配置@Aspect切面的bean创建代理,织入切面
开启组件扫描 <context:component-scan base-package="com.wpq.Spring"/>
2.创建切面类:给类上面添加@Aspect注解
3.切面类中配置切入点 :@Pointcut(value = "execution(* com.wpq.service.impl.*.*(..))")
public void pointCut() {}
4.在切面类不同的方法中添加注解:
前置:@Before(value=“pointCut()”)
环绕: @Around(value=“pointCut()”)
后置: @AfterReturning(value=“pointCut()”)
异常: @AfterThrowing(value=“pointCut()”)
最终: @After(value=“pointCut()”)
更改多个切面类的执行顺序的方法有几种
① 默认按照类的首字母来执行,a-z/A-Z
② 给切面类添加 @Order(v) 注解,v越小,优先级越高
③ 切面类实现Order接口,重写getOrder()方法
完全注解
(1)创建配置类,不需要xml文件
AOP(AspectJ配置文件)
1.创建增强类和被增强类,创建方法
2.在spring配置文件中创建两个类对象
3.在spring配置文件中配置切入点
JDBC Template
什么是JDBC Template
(1)Spring框架对JDBC进行封装,使用JDBC Template方便对数据库操作
准备工作
(1)引入相关依赖
(2)在spring配置文件中,配置数据库连接池
(3)配置 JDBC Template对象,注入DataSource
(4)创建service和dao类,在dao注入
相关概念
spring DAO 有什么用?
Spring DAO 使得 JDBC,Hibernate 或 JDO 这样的数据访问技术更容易以一种统一的方式工作。这使得用户容易在持久性技术之间切换。它还允许您在编写代码时,无需考虑捕获每种技术不同的异常。
列举 Spring DAO 抛出的异常。
spring-data-access-exception
spring JDBC API 中存在哪些类?
JdbcTemplate
SimpleJdbcTemplate
NamedParameterJdbcTemplate
SimpleJdbcInsert
SimpleJdbcCall
JDBC数据库操作
JDBC数据库操作(添加)
1.数据库创建实体类
2.编写service和dao
(1)在dao进行数据库添加操作
(2)调用JdbcTemplate对象里面update方法实现添加操作
测试方法:
JDBC数据库操作(修改+ 删除)
Dao接口:
DaoImpl中sql语句
测试
JDBC数据库操作(查询)
返回某个值
1.查询记录条数
方法
第一个参数:sql语句
第二个参数:返回类型 . class
返回某对象
测试:
方法
方法
第一个参数:sql语句
第二个参数:RowMapper:是接口,返回不同类型数据,使用这个接口里面实现类完成数据封装
第三个参数:sql语句值
返回集合
测试:
方法
方法
第一个参数:sql语句
第二个参数:RowMapper:是接口,返回不同类型数据,使用这个接口里面实现类完成数据封装
第三个参数:sql语句值
JDBC数据库操作(批量操作)
批量添加
方法
第一个参数:sql语句
第二个参数:list集合,添加多条数据
实现
测试:
批量修改+删除
批量修改
事务管理
事务概念
事务是数据库操作最基本单元,要么都成功、要么都失败
事务特性(ACID)
- 原子性
- 一致性
- 隔离性
- 持久性
事务操作
搭建事务操作环境
1.创建数据库表,添加记录
2.创建service和dao,完成对象的创建和注入
(1)service注入dao,在dao注入JDBCTemplate,在JDBCTemplate注入DataSource
3.在dao中创建两个方法,在
在dao中
在service
测试:
若产生异常会出问题,此时需要通过事务解决
事务操作过程
- 开启事务操作
- 进行事务操作
- 无异常,提交事务
- 有异常,事务回滚
事务管理
添加在JavaEE三层结构里的Service层(业务逻辑层)
- 编程式事务管理
- 声明式事务管理(底层使用AOP原理)
- 基于注解
- 基于配置文件
事务管理API
提供一个接口,代表事务管理器,针对不同框架提供不同实现类
PlatformTransactionManager
声明式事务管理
基于注解
- 创建事务管理器
- 开启事务注解
(1)在spring配置文件引入名称空间
(2)开启事务注解
3.在service类上,添加事务注解
(1)@Transactional,这个注解添加到类上、方法
- 类:该类所有方法都添加事务
- 方法:为该方法添加事务
声明式事务管理参数配置
1.在service类上添加注解@Transactional,可以在该注解中配置相关参数
- propagation:事务传播行为(多事务方法直接进行调用,这个过程中,事务是如何管理)
- isolation:事务隔离级别
事务有特性成为隔离性,多事务操作之间不会产生影响,不考虑隔离性会产生很多问题
(1)三个读问题:脏读、不可重复读、幻读通过隔离级别解决
- timeout:超时设置,以秒为单位
事务需要在一定时间内提交,若超时则回滚
- readOnly :是否只读
默认false,可增删改查
设置为true,则只能查询
rollbackFor:回滚
设置出现哪些异常进行事务回滚noBackFor:不回滚
设置出现哪些异常不进行事务回滚
基于xml配置文件(声明式)
1.在spring配置文件中进行配置
第一步:配置事务管理器
第二步:配置通知
第三步:配置切入点和切面
完全注解声明式事务管理
Spring 事务失效的场景有哪些?
1.业务方法中异常被try-catch掉,导致异常没有抛出,没有触发回滚,事务失效
2.在非public修饰的业务方法上使用事务注解,会导致事务失效
3.数据库引擎不支持事务
4.打上事务注解的方法所在的类并没有交给spring的IOC容器管理,同样会导致事务失效
5.业务方法中的运行时异常被try-catch之后,在catch里面抛出的异常类型不是运行时异常,同样会导致事务失败,因为如果不在事务注解中声明触发回滚类型,默认的是RuntimeException
6.自身调用问题,业务层自身非事务方法调用事务方法,会导致不经过Spring的代理类。默认只有在外部调用事务方法,事务才会生效
@Transactional(readOnly = true)的理解
某个事务被指定只读属性为true的时候,相当于在该事务执行期间,把数据库设置成了只读数据库,换句话说就是该事务在执行期间,是看不见其它事务提交的数据的。
#@Transactional(timeout= 2)的理解?
从事务开始得两秒钟后,数据库还未返回结果,Spring就会抛出TransactionTimedOutException。
Spring读取properties文件的方式
ClassPathResource resource = new ClassPathResource("conf/db.properties");
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
String o = properties.getProperty("jdbc.url");