spring整理复习
# spring使用流程
首先创建一个spring对象,他要读取spring的配置文件,
sping配置文件里面要写对象名字就是id和类路劲
来创建对象,他把创建好的对象放进容器里
## 使用:
使用这个对象的getben方法。获取创建好的对象
# 创建:
```
# 使用的是无参构造方法创建
# 用的是动态代理实现
```
# 设值注入:
##
## 本质:
```
就是创建对象时给属性赋值
```
### 设值注入的分类:
```
#set注入 调用类中的set方法赋值(使用较多)
#构造注入 调用类中的有参构造方法赋值
```
### 设值注入的实现分类
```
#基于xml文件的依赖注入方式(基于xml的di):使用配置文件的标签属性实现
#基于注解方式的依赖注入方式(基于注解的di):使用注解
```
##
## 基于xml文件的set方式注入
```xml
bean标签中使用property标签就是set注入
property:属性
<bean id="" class:"xxx.xxx.xxx">
<property name='' value=''/>
<property name='' ref=''/>
</bean>
给对象属性赋值,你得创建对象才能赋值给对象属性吧?
首先给一个有属性是对象类型的对象:
<bean id="myschool" class:"xxx.xxx.xxx">
<property name='name' value='大学'/>
<property name='student' ref='mystudent'/>
</bean>
<bean id="mystudent" class:"xxx.xxx.xxx">
<property name='name' value='张三'/>
<property name='age' ref='12'/>
</bean>
```
## !!1基于xml文件的构造方法注入:
```xml
如上。只不过标签换成了constructor
constructor:构造方法 亢四chua客t
<bean id="" class:"xxx.xxx.xxx">
<constructor-arg name='' value='' index:'0'/>
<constructor-arg name='' ref='' index:'1'/>
</bean>
name:表示构造方法的形参名
index:表示构造方法参数位置,从左往右 从0开始
value:简单类型用value
ref:引用类型用ref
```
### 1.构造注入创建文件对象 (举一反三,就看类属性赋什么值就完事了)
```xml
<bean id="myfile" class:"java.io.File">
<constructor-arg name='parent' value='d:\course\java' index:'0'/>
<constructor-arg name='child' value='学习资料.txt' index:'1'/>
</bean>
```
###
## 引用类型的自动设值注入:
```xml
作用:就是你在赋值引用类型对象时,不用自己在赋值了,直接框架自动注入
分类:
1:byname
2:bytype
autowire翻译:自动装配
<bean id="" class:"xxx.xxx.xxx" autowire:'byName/byType'>
<property name='' value=''/>
<property name='' ref=''/>
</bean>
byname演示
<bean id="" class:"xxx.xxx.xxx" autowire:'byName'>
<property name='name' value='大学'/>
<!--<property name='student' ref='studet'/>
原本要赋值引用类型对象要这样的,现在不用了
这个是set注入,所以看的是set后缀名。进行找
比的是id和set名。
-->
</bean>
<bean id="student" class:"xxx.xxx.student">
<property name='name' value='张三'/>
<property name='age' ref='12'/>
</bean>
byType演示
<!--按类型注入,只要是同源关系就可以。
同源一类的意思,以下都是同源:
1,引用数据的数据类型和bean的class值一样,就是说包都要是一样的,完全同一个类
2,引用数据的数据类型和bean的class值是父子类关系
3,引用数据的数据类型和bean的class的值接口和实现类的关系。
注意多一个都是错的。只能一个符合要求!
-->
```
## 多配置文件
```xml
多配置文件的好处
1:每个文件小很多,效率高。、
2:避免多人竞争
多配置文件的分类:
1:按功能,一个模块一个配置文件
2:按类的功能:数据库一个配置文件。做事务的一个配置文件
```
```xml
包含关系的配置文件:
spring-total表示主配置文件:包含其他配置文件,一般不定义对象
语法:<import resource="其他文件的路径"/>
关键字:classpath:表示类路径(class文件所在的目录),
spring的配置文件中要制定其他文件的位置,需要使用classpath告诉他加载类路劲
```
## !!2基于注解方式的设值注入(di)
```
使用步骤:
1,加入maven的依赖,spring-context,再加入这个的依赖时就加入了aop的依赖
使用注解必须使用spring-aop依赖
2,在类中加入spring注解
3.在spring配置文件中加入组建扫描器,告诉spring注解项目位置
```
```
要学习的注解:
1,@component(创建对象)
2.@respotory(创建持久层类上面:放在dao的实现类上面。)
3.@service(业务层,业务处理,像事务啊这种的。)
4.@Contorller(控制器,能够接受用户提交的参数,和显示请求处理结果)
5.@value
6.@Autowired
7.@Resource
```
# @Component注解
```xml
component:组成,成分 它是用来创建对象的
创建对象的等同于<bean>的功能
value是对象名称,也就是bean中的id值
这个值一定是唯一的,spring容器中就一个
@Component(value="mystudent")等于
<bean id='mystudent' class="com.hello.student"/>
这个value可以省略
对象名为类名首字母小写
```
## 赋值:
## 1,简单类型赋值
```java
简单类型赋值两种位置赋值:
1,在属性定义上赋值,无需set方法
@value(value='xxx')
private String name;
2,在set方法上赋值
@value(value='xxx')
public void setName(String name){
this.name=name;
}
```
## 2,引用类型赋值:
### 1,autowried方式
```
引用类型使用的是
@AutoWired注解
使用的是自动注入原理(默认是byType)
注入方式有:byType和byName
注意:如果你非要用byName的方式。那么就需要这样写
@Autowired
@Qualifier("名字")
Qualifier:翻译为限定符
注解位置:
1,属性定义上面
2,set方法上面
AutoWired中的required属性:
required翻译:必须的,规定的 瑞快尔
他的值为fales/true
Autowried(required=flase):表示程序正常执行,引用类型是null
Autowried(required=ture):表示引用类型赋值失败时程序终止,报错
```
### 2,jdk提供的方式:
```java
@resource:
来自jdk提供,spring框架提供了该功能支持,
默认使用byName方式注入,如果注入失败那么就使用byType
如果只想让它使用byName方式需要加个属性 :nane (name的值是bean的id)
只使用byName
@resource(name='bean的id')就是对象的名字
```
## 注解解耦合
```properties
name=张三
age=24
```
```xml
<context:property-placeholder location='classpath:text.properties/>
```
```java
@value(${name})
private String name;
@value(${age})
private int age;
```
# AOP
```
有两种代理方式:一个是jdk动态代理
一个是CJLIB
```
```
词汇:
orient:面向,对着 读音:奥润特
aspect:切面 读音:啊四排克特
programming:编程 读音:谱如关明
joinPoint:连接点 读音:join破音特
pointcut:切入点
advice:通知
Target:目标对象
modifiers:修改器
param:参数
proceed:继续
proceeding:程序 ,行动 读音:破sei定
pattern :模式,方式 读音:排藤
ret:技术,返回 读音:ruai特
declaring:宣告行为,说明 读音:地可来ring
modifiers-pattern] 访问权限类型
ret-type-pattern 返回值类型
declaring-type-pattern 包名类名
name-pattern(param-pattern) 方法名(参数类型和参数个数)
throws-pattern 抛出异常类型
```
```
理解切面编程?
1)需要分析项目功能,找出切面。
2)安排切面执行时间(在目标方法前或者后)
3)安排切面执行位置(什么类,什么方法)
```
```
aop实现
aop的实现用aspectj(面向切面编程,读音:哎四排克j)不用spring自带的实现,很笨重。
实现两种方式:
1,使用xml文件:配置全局事务
2,使用注解(常用)
```
```
学习切面执行时间时,要学习5个注解,这个执行时间叫advice(通知,增强)
1)@Before(以前)
2)@AfterReturning(后置)
3)@Around(围绕)
4)@AfterThrowing(通知,抛出异常)
5)@After(之后,照顾)
```
```
切入点表达式:
execution(modifiers-pattern? ret-type-pattern
declaring-type-pattern?name-pattern(param-pattern)
throws-pattern?)
execution(访问权限? 返回类型 包名? 方法名(参数) 抛出异常?)
```
```
execution(public * *(..))
指定切入点为:任意公共方法。
execution(* set*(..))
指定切入点为:任何一个以“set”开始的方法。
execution(* com.xyz.service.*.*(..))
指定切入点为:定义在 service 包里的任意类的任意方法。
execution(* com.xyz.service..*.*(..))
指定切入点为:定义在 service 包或者子包里的任意类的任意方法。“..”出现在类名中时,后
面必须跟“*”,表示包、子包下的所有类。
execution(* *..service.*.*(..))
指定所有包下的 serivce 子包下所有类(接口)中所有方法为切入点
execution(* *.service.*.*(..))
指定只有一级包下的 serivce 子包下所有类(接口)中所有方法为切入点
execution(* *.ISomeService.*(..))
指定只有一级包下的 ISomeSerivce 接口中所有方法为切入点
execution(* *..ISomeService.*(..))
指定所有包下的 ISomeSerivce 接口中所有方法为切入点
execution(* com.xyz.service.IAccountService.*(..))
指定切入点为:IAccountService 接口中的任意方法。
execution(* com.xyz.service.IAccountService+.*(..))
指定切入点为:IAccountService 若为接口,则为接口中的任意方法及其所有实现类中的任意
方法;若为类,则为该类及其子类中的任意方法。
execution(* joke(String,int)))
指定切入点为:所有的 joke(String,int)方法,且 joke()方法的第一个参数是 String,第二个参
数是 int。如果方法中的参数类型是 java.lang 包下的类,可以直接使用类名,否则必须使用
全限定类名,如 joke( java.util.List, int)。
execution(* joke(String,*)))
指定切入点为:所有的 joke()方法,该方法第一个参数为 String,第二个参数可以是任意类
型,如joke(String s1,String s2)和joke(String s1,double d2)都是,但joke(String s1,double d2,String
s3)不是。
execution(* joke(String,..)))
指定切入点为:所有的 joke()方法,该方法第一个参数为 String,后面可以有任意个参数且
参数类型不限,如 joke(String s1)、joke(String s1,String s2)和 joke(String s1,double d2,String s3)
都是。
execution(* joke(Object))
指定切入点为:所有的 joke()方法,方法拥有一个参数,且参数是 Object 类型。joke(Object ob)
是,但,joke(String s)与 joke(User u)均不是。
execution(* joke(Object+)))
指定切入点为:所有的 joke()方法,方法拥有一个参数,且参数是 Object 类型或该类的子类。
不仅 joke(Object ob)是,joke(String s)和 joke(User u)也是。
```
```xml
aop的aspectsj依赖maven
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId> <version>5.2.5.RELEASE</version>
</dependency>
```
AOP的实现
```java
1,首先要在类上声明他是切面类像这样
@Aspect
public class hello{
}
2,切面类的方法定义要求:
1,公共方法public
2,方法没有返回值
3,方法名称自定义
4,方法参数可以有,也可以无
只能使用固定的几个参数类型
```
(以下都是无参数)
## 1:@before(之前)
```
@Before
属性:value,写切入点表达式
位置:方法上面
特点:
1)在目标方法之前先执行
2)不会改变目标方法执行结果
3)不会影响目标方法执行结果
```
```java
实现:java类中
@Aspect
public class hello{
@Before(
value="execution(访问权限? 返回类型 包名? 方法名(参数)
抛出异常?)"
public void one(){
}
}
```
```xml
xml文件的实现:
<aop:aspectj-autoproxy/>
```
(切面方法有参数了)
```java
JoinPoint 连接点
作用:获取目标方法执行的信息,例如方法名称,方法实参
如果需要目标方法的信息,就加入JoinPoint参数
注意:他必须是第一个参数
@Aspect
public class hello{
@Before(
value="execution(访问权限? 返回类型 包名? 方法名(参数)
抛出异常?)"
public void one(JoinPoint j){
}
}
```
## 2,@AfterReturning: 后置参数
```
@AfterReturning
属性:1,value。切入点表达式
2,returning 目标方法返回值、
位置:在方法定义的上面
特点:
1,在目标方法之后执行
2,可以获取目标方法的返回值
3,可以修改这个返回值
```
```java
@AfterReturning实现
@Aspect
public class hello{
@AfterReturning(
value="execution(访问权限? 返回类型 包名? 方法名(参数)
抛出异常?)",returning="返回值名字")
public void one(JoinPoint j,object 这里写上面的返回值名字){
}
}
```
## 3,@Around 环绕通知
```java
@Around
属性:value 切入点表达式
位置:方法上面
特点:
1.他是功能最强大的通知
2,在目标方法前/后,执行都能增强
3,控制目标方法是否调用执行
4,修改目标方法执行结果,影响最后调用结果
定义:
1,必须有返回值,推荐object
2,public
3,方法名称自定义
4,方法有参数,固定参数proceedingJoinPoint
@Aspect
public class hello{
@Around(
value="execution(访问权限? 返回类型 包名? 方法名(参数)
抛出异常?)")
public object one(JoinPoint j,
proceedingJoinPoint 随便){
//可以加东西,也可以控制目标方法执行
//这个方法调用了目标方法并返回了值
Object 目标方法返回值=随便.proceed();
}
}
```
## 4,@afterThrowing:异常通知
```
@afterThrowing
属性:
1,value 切入点表达式
2,Throwing 自定义的变量,表示目标方法抛出的异常对象
变量名必须和方法的参数名一样
位置:方法上面
特点:
1.在目标抛出异常时执行
2,可以做异常监控程序
监控方法是否有异常,有异常时可以通知开发人员,发短信邮件等
定义:
1,public
2,无返回值
3,方法名称自定义
4,方法可以没有参数,有就是joinPoint,
```
## 5,@after: 最终通知
```
@after
属性:value 切入点表达式
位置:方法上面
特点:
1.总是执行
2,目标方法之后执行
定义:
1,public
2,无返回值
3,方法名称自定义
4,方法可以没有参数,有就是joinPoint,
```
## 6,@pointcut
## 用来定义切入点表达式,减少重复劳动
```java
@pointcut定义方法上面,此时这个方法名称急速切入点表达式别名
其他通知中,value属性就可以使用这个方法名称,代替切入点表达式
@pointcut(value="execution(execution(访问权限? 返回类型 包名? 方法名(参数)抛出异常?))")
public void hhh(){
//无需代码
}
其他使用时
@After(value="hhh()")
public void one(){
//方法增强
}
```
```
有接口用jdk动态代理
无接口用cglib,原理是继承
```
# 整合mybatis
```
步骤:
1,加依赖
2,创建dao接口和mapper文件
3,创建mybatis主配置文件
4,创建service接口和实现类,属性是dao
5,创建spring配置文件,吧mybatis对象交给spring管理
```
```xml
pom依赖
1,spring依赖
2,mybatis依赖
3,mysql依赖
4,spring事物依赖
5,mybatis和spring集成依赖
<dependencies>
spring依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
spring事务依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
mybatis依赖
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
spring和mybatis集成
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
mysql驱动
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
连接池
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
```
```xml
spring配置文件
1,创建德鲁伊数据源
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
使用的是set注入
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxActive" value="20"/>
</bean>
2,创建sqlsessionFactory对象
使用的是,sqlsessionfactoryBean类
<!--主配置文件,一个是德鲁伊的对象,一个是mybatis配置文件-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="configLocation" value="classpath:mybatis.xml"/>
</bean>
3,创建dao对象
<!--
Configurer:配置器 Scanner:扫描
MapperScannerConfigurer内部调用的是sqlsession.getMaooer(dao接口.class)
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="dao所在的包"/>
</bean>
```
```java
测试
ApplicationContext applicationContext=new
ClassPathXmlApplicationContext("applicationContext.xml");
dao接口 dao= applicationContext.getBean("dao对象,名字就是dao的首字母小写");
```
## 用配置文件
```xml
placeholder:占位符 property:属性
<context:property-placeholder location:"classpath:配置文件路径"/>
然后这样用
<property name="xxx" value="${属性配置文件中的key}"
```
## 使用事物
```java
1,什么是事物:事物是多条sql语句的集合,
当我们希望多条sql语句都能成功或者失败,sql语句执行是一致的,作为一个整体执行
2,什么时候用事物
当我的操作涉及多个表,或者多条语句同时成功才能完成我的功能,或者都失败,保证操作符合要求
3,事物应该放在哪里
service类的业务方法上,因为业务方法会调用多个dao方法,执行多个sql语句
4,多种数据库访问技术,有不同的事物处理机制,对象,方法比较不好,该怎么解决
5,spring提供了一种处理事物的统一模型,能使用统一步骤,方式完成多种数据库访问技术的事物处理
6,处理事物需要怎么做,做什么
//Transaction:事物。事物处理,业务,交易 platForm:平台 hibernate:冬眠,休眠
接口:platformTransactionManager
实现类:
mybatis-----dataSourceTransactionManager
hibernate-----hibernateTransactionManager
使用:
1)声明:
直接在spring配置文件中声明你用的是什么数据库访问技术
<bean id='xxx' class='...dataSourceTransactionManager'
2)说明需要什么样的事物
1,事物隔离级别(4个值)
default:使用数据库默认事物隔离级别。mysql默认为:REPEATBLE_READ
oracle默认为READ_COMMITTED
READ_UNCOMMITTED(uncommitted:未提交):读未提交,未解决任何并发问题
READ_COMMITTED(committed:commit):读已提交,解决脏读,存在不开重复读和幻读
REPETATBLE_READ(repe:重复):可重复读,解决脏读,不可重复读,存在幻读
SERIALIZABLE(serializable:可串行化,序列化):串行化,不存在并非问题。
2,事物超时时间
表示一个方法最多执行时间,如果方法执行超过了时间,事物就回滚
单位是秒,整数值,默认是-1
3,事物的传播行为
控制业务方法是不是有事物的,是什么样的事物,
7个传播行为,表示你的业务方法调用时,事物在方法之间是如何使用的
PROPAGATION_REQUIRED(propagation:传播 读音:爬波key生
required:必须,必读读音:瑞快尔的):
有事务时就加入事务,无事务时就创建新的事务
PROPAGATION_REQUIRED_NEW():就是说无论如何都是新建事务,如果有事务,那么就挂起已有的事务 ,直到执行完新建的事务
PROPAGATION_SUPPORTS(supports:支持忍受 读音:四破四):就是说支持事务,
但是没有事务事务时也可以以非事务执行。就比如select语句就可以不用事务
还有其他四个
3)事物提交事物,回滚事务的时机
1,当你的方法执行成功,没有异常抛出,方法执行完成,spring在方法执行后提交事物,事务管理器commit
2,当你的业务方法抛出运行时异常或error,spring执行回滚,调用事物管理器的rollback
运行时异常定义:runtimeException,和他的子类都是运行时异常,比如空指针异常,数字格式异常
3,当你的业务方法抛出非运行时异常,主要是受查异常时,提交事物
受查异常,在你写代码中,必须处理的异常。ioException。sqlException
```
## 注解依赖
```
spring框架提供事物处理方案
1,适合中小项目使用,注解方案。
spring使用的是aop实现业务方法增加事物的功能,使用Transactional(事物处理)
位置:public方法上面,表示当前方法具有事物。
值:可以给注解的属性赋值,表示具体的隔离级别,传播行为,异常信息等等
```
### 使用步骤
```XML
1,声明事物管理器对象
<bean id ="xx" class="datasourceTransactionManager就是spring实现的数据库实体类"/>
```
```JAVA
2,在需要事物的方法上加@Trancational
可选属性:
propagation:用于设置事物传播属性。该属性类型为isolation(隔离)枚举类型 、
默认值为PROPAGATION_REQUIRED
readOnly:用于设置该方法对数据库的操作是否是只读,该属性是boolean 默认值为false
timeout:用于设置本操作与数据库连接的超时时限。单位为秒,类型为int,默认值为-1,就是没有时限
rollbackFor:指定需要回滚的异常类,类型为Class[],默认值为空数组,当然,
若只有一个异常类时,可以不使用数组
rollbackForClassName:指定需要回滚的异常类类名,类型为String[],默认值为空数组。
当然只有一个异常类时,可以不使用数组
noRollbackFor:制定不需要回滚的异常类。类型为classp[],默认为空数组,当然只有一个类时,可以不用数组
noRollbackForClassName:制定不需要回滚的异常类类名,类型为string[],默认为空数组,只有一个异常类
可以不使用数组
```
```java
Transactional:事务处理
3,开启事物注解驱动
@Around环绕
Object one(){
try{
buy();
事物管理.commit();
}catch(Excetion e){
事物管理.rollback();
}
}
```
## XML方式
```xml
1)maven依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.3.5.release</version>
</dependency>
2)声明事物管理器对象
<bean id='xx' class='org.springframework.jdbc.datasource.DataSourceTransactionManager'/ >
3)声明方法需要的事物类型(配置方法的事物属性[隔离级别,传播行为,超时])
attribuites:属性 读音:啊吹biu四
<tx:advice id="自定义名称" transaction-manager="事务管理器的id,就是第二部的id">
<tx:attribuites>
<tx:method name="1)完整的方法名称,不带包和类,2)方法可以使用通配符,*表示任意字符"
propagation="传播行为" isolation="隔离级别" rollback-for="一定回滚的异常"/>
</tx:attribuites>
<tx:method name
</tx:advice>
4)配置aop:制定哪些类需要创建代理
配置增强器
<aop:congfig>
<aop:pointcut id="" expression="切入点表达式"/>
<aop:advisor advice-ref="通知,上面tx:advice哪里的配置" pointcut-ref="切入点表达式的id"/>
</aop:congfig>
```
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器