概述
Spring
1.什么是Spring
它是一个容器,它是整合其他框架的框架;它的核心是IOC和AOP,它由20多个模块组成,在很多领域都提供优秀的解决方案。
2.Spring的特点
-
轻量级
20多个模块构成,每个jar都小于1M,核心包就3M左右;对代码无污染。
-
面向接口编程
使用接口就是面向灵活,项目的可扩展性和可维护性都提高;接口不关心实现类的类型,使用时接口指向实现类,切换实现类疾控科交换这个功能。
-
AOP面向切面编程
就是将公共的、重复的、通用的代码单独开发,在需要的时候反织回去;底层的原理是动态代理。
-
整合其他框架
它整合后使用其他框架更加容易。
3.什么是IOC
控制反转IOC是一个概念、一种思想。由Spring容器进行对象的创建和依赖注入,程序员在使用时直接取出使用。
- 正转:由程序员进行对象的创建和依赖注入。
- 反转:由Spring容器进行对象的创建和依赖注入,将控制权从程序员手中夺走交给Spring容器。
4.基于xml的IOC
-
创建对象
<!-- 创建学生对象 等同于 Student student = new Student(); id:创建对象的名称、 class:创建对象的类型(底层发射机制), 容器启动时,对象就被创建。 --> <bean id="stu" class="com.jv.pojo.Student"></bean>
-
给创建对象赋值
-
使用setter注入
-
简单类型注入:值用value属性
-
引用类型注入:值用ref属性
注意:使用setter注入必须提供无参的构造方法,必须提供set方法
<bean id="school" class="com.jv.pojo2.School"> <property name="name" value="清华大学"></property> <property name="address" value="海淀区"></property> </bean> <bean id="stu" class="com.jv.pojo2.Student"> <property name="name" value="lis"></property> <property name="age" value="22"></property> <property name="school" ref="school"></property> </bean>
测试时这样拿到对象:
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext ("s02_/applicationContext.xml");//spring提供xml解析 School sch = (School) ac.getBean("school");//取对象 Student stu = (Student) ac.getBean("stu");
-
-
使用构造方法注入
- 使用构造方法的参数名称进行赋值
- 使用构造方法的参数下标赋值
- 使用默认构造方法的参数顺序赋值
-
5.构建三层架构项目
- 非Spring接管:
-
实体类:
com.jv.pojo Users
-
数据访问层:
com.jv.dao UsersMapper.java(接口)
UsersMapperImpl.java(实现类/MyBatis)
-
业务逻辑层:
com.jv.service UsersService(接口)
UsersServiceImpl.java(实现类)
-
界面层:
com.jv.controller UsersController.java
注意:所有的业务逻辑层中都必定持有数据访问层的对象,所有界面层中都必定持业务逻辑层的对象;由数据访问层的实现类真正的干活。
6.基于注解的IOC
也称为DI(Dependency Injection),它是IOC的具体实现技术。基于注解的IOC必须要在Spring的核心配置文件中添加包扫描。
-
创建对象的注解
@Component:可以创建任意对象;创建的对象默认名称是驼峰命名,也可指定对象的名称@Component(“”)
@Controller:专门依赖创建控制器的对象(Servlet),这种对象可以接受用户请求,可返回处理结果给客服端
@Service:专门用来创建业务逻辑层的对象,负责向下访问数据访问层,处理完毕后的结果返回给界面层
@Repository:专门用来创建数据访问层的对象,负责数据库中的增删改查所有操作
-
依赖注入的注解
-
简单类型的注入
@Value:赋值
-
引用类型的注入
-
@Autowired:使用类型注入值,从整个Bean工厂中搜索同源类型的对象进行注入
同源类型:被注入的和注入的类型完全相同或者为父子类或接口和实现类
-
@Autowired+@Qualifier:使用名称注入值,从整个Bean工厂中搜索相同名称的对象进行注入
-
-
7.Spring支持的AOP编程
- Before通知:在方法被调用前调用
- After通知:在目标方法被调用后调用
- Throw通知:目标方法抛出异常时调用
- Around通知:拦截目标对象方法调用
8.AOP常用术语
- 切面:重复的、公共的、通用的功能称为切面,例如:日志、事务、权限等
- 连接点:就是目标方法,要在目标方法中实现目标功能和切面功能(增强功能)
- 切入点(Pointcut):指定切入位置,多个连接点构成切入点;切入点可是一个目标方法、可是一个类中的所有方法、也可是某个包下的所有类中的方法
- 目标对象:操作谁,谁就是目标对象
- 通知(Advice):用来指定切入的时机,是在目标方法执行前、执行后、出错时、环绕目标切入切面功能
9.AspectJ框架
AspectJ 是一个优秀的面向切面的框架,它可扩展了java语音提供了强大的切面实现。无缝扩展、易学易用。
10.AspectJ常见通知类型
- 前置通知@Before
- 后置通知@AfterReturning
- 环绕通知@Around
- 最终通知@After
- 定义切入点@Pointcut
11.AspectJ的切入点表达式
- 规范公式:execution(访问权限 方法返回值 方法声明(参数) 异常类型)
- 简化公式:execution(方法返回值 方法声明(参数)
用到的符合:
-
*:代表任意的字符(通配符)
-
…:如果在方法的参数中表示任意参数;如果在路径中表示本路径及其所有的子路径
12.前置通知的切面方法@Before
添加依赖:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
实现步骤:
-
创建业务接口
-
创建业务实现类(写目标方法)
-
创建切面类,实现切面方法
-
在applicationContext.xml文件中进行切面绑定
<!-- 绑定--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy><!--绑定时默认是JKD动态代理,取值要用接口--> <!--proxy-target-class="true"表示切换为CGLib动态代理(子类代理),取值可用接口和实现类--> <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> <!-- 推荐全部用接口接-->
规范:
-
访问权限为public
-
方法的返回值为void
-
方法名称自定义
-
方法没有参数,如有只能为JoinPoint类型
-
必须使用@Before注解来声明切入点和时机是前切功能
参数:value :指定切入点的表达式
//public String doSome(String name, int age) @Aspect//交给Aspect框架 public class MyAspect { @Before(value = "execution( * com.jv.s1.*.*(..))")//切入点+切入表达式execution public void myBefore(){ System.out.println("前置功能》。。"); } }
13.后置通知的切面方法@AfterReturning
-
规范:
-
访问权限为public
-
方法的返回值为void
-
方法名称自定义
-
方法有参数(也可以没有,如果目标方法没有参数则可以写无参的方法,一般写有参可同时处理),这个切面方法的参数就是目标方法的返回值
-
必须使用@AfterReturning注解来表明是后置通知
参数:
value :指定切入点的表达式
returning:指定返回的目标方法返回值的名称,该名称必须与切面方法的参数名称一致
@Aspect//交给Aspect框架 @Component//创建对象 public class MyAspect { @AfterReturning(value = "execution(* com.jv.s2.*.*(..))", returning = "obj") public void myAfterReturning(Object obj){ System.out.println("后置功能》。。"); } }
-
-
注意:如果在切面方法中拿到目标方法的返回值后,如果目标方法中的返回值是简单类型8基本加String则不可改变,如果目标方法中的返回值是引用类型则可以改变。
13.环绕通知@Around
它是通过拦截目标方法的方式,在目标方法前后增强功能的通知;它是功能最强大的特征,一般事务使用此通知。它可以轻易的改变目标方法的返回值。
-
规范:
-
访问权限为public
-
方法的返回值为目标方法的返回值
-
方法名称自定义
-
方法有参数,参数就是目标方法
-
回避异常
-
使用@AfterReturning注解来表明是环绕通知
参数:
value :指定切入点的表达式
@Around(value = "execution(* com.jv.s2.*.*(..))") public Object myAround(ProceedingJoinPoint pjp) throws Throwable { System.out.println("up..."); Object o = pjp.proceed(pjp.getArgs()); System.out.println("down..."); return o.toString().toUpperCase(); }
-
14.最终通知@After
无论目标方法是否正常执行,最终通知的代码都会被执行。
-
规范:
-
访问权限为public
-
方法没有返回值
-
方法名称自定义
-
方法没有参数,有也只能为JoinPoint
-
使用@After注解来表明是最终通知
参数:
value :指定切入点的表达式
-
15.切入点表达式起别名@Pointcut
@Pointcut(value = "execution(* com.jv.s2.*.*(..))")
public void myCut(){}
@Around(value = "myCut()")//调用
16.基于注解的事务添加步骤
1)在applicationContext_service.xml文件中添加事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--因为事务必须关联数据库处理,所以要配置数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
2)在applicationContext_service.xml文件中添加事务的注解驱动
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
3)在业务逻辑的实现类上添加注解@Transactional(propagation = Propagation.REQUIRED)
REQUIRED表示增删改操作时必须添加的事务传播特性
17.@Transactional注解参数详解
@Transactional(propagation = Propagation.REQUIRED,//事务的传播特性
noRollbackForClassName = "ArithmeticException", //指定发生什么异常不回滚,使用的是异常的名称
noRollbackFor = ArithmeticException.class,//指定发生什么异常不回滚,使用的是异常的类型
rollbackForClassName = "",//指定发生什么异常必须回滚
rollbackFor = ArithmeticException.class,//指定发生什么异常必须回滚
timeout = -1, //连接超时设置,默认值是-1,表示永不超时
readOnly = false, //默认是false,如果是查询操作,必须设置为true.
isolation = Isolation.DEFAULT//使用数据库自已的隔离级别
)
18.Spring的两种事务处理方式
1)注解式的事务
使用@Transactional注解完成事务控制,此注解可添加到类上,则对类中所有方法执行事务的设定.此注解可添加到方法上,只是对此方法执行事务的处理.
2)声明式事务
在配置文件中添加一次,整个项目遵循事务的设定.
19.Spring中事务的五大隔离级别
1).未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
2).提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
3).可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读,但是innoDB解决了幻读
4).串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
5).使用数据库默认的隔离级别isolation = Isolation.DEFAULT
MySQL:mysql默认的事务隔离级别是Repeated-Read可重复读。
Oracle:oracle数据库支持READ COMMITTED 和 SERIALIZABLE这两种事务隔离级别。默认系统事务隔离级别是READ COMMITTED,也就是读已提交
20.为什么要添加事务管理器
JDBC: Connection con.commit(); con.rollback();
MyBatis: SqlSession sqlSession.commit(); sqlSession.rollback();
Hibernate: Session session.commit(); session.rollback();
不同技术的事务提交和回滚都不同,所以事务管理器是用来生成相应技术的连接+执行语句对象。
如果使用MyBatis框架,必须使用DataSourceTransactionManager类完成处理
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--因为事务必须关联数据库处理,所以要配置数据源-->
<property name="dataSource" ref="dataSource"></property>
</bean>
提示:项目中的所有事务,必须添加到业务逻辑层上。
21.Spring事务的传播特性
多个事务之间的合并,互斥等都可以通过设置事务的传播特性来解决。
-
常用
PROPAGATION_REQUIRED:必被包含事务(增删改必用)
PROPAGATION_REQUIRES_NEW:自己新开事务,不管之前是否有事务
PROPAGATION_SUPPORTS:支持事务,如果加入的方法有事务,则支持事务,如果没有,不单开事务
PROPAGATION_NEVER:不能运行中事务中,如果包在事务中,抛异常
PROPAGATION_NOT_SUPPORTED:不支持事务,运行在非事务的环境 -
不常用
PROPAGATION_MANDATORY:必须包在事务中,没有事务则抛异常
PROPAGATION_NESTED:嵌套事务
22.声明式事务
声明式事务是Spring非常有名的事务处理方式。
要求项目中的方法命名有规范:
- 完成增加操作包含: add、save、insert、set
- 更新操作包含: update、change、modify、edit
- 删除操作包含: delete、drop、remove、clear
- 查询操作包含: select、find、search、get、query
提示:配置事务切面时可以使用通配符*来匹配所有方法
- 修改声明式事务后的applicationContext_service.xml文件:
<!-- 创建事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 配置事务切面-->
<tx:advice id="myadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*select*" read-only="true"/>
<tx:method name="*find*" read-only="true"/>
<tx:method name="*get*" read-only="true"/>
<tx:method name="*search*" read-only="true"/>
<tx:method name="*insert*" propagation="REQUIRED"/>
<tx:method name="*add*" propagation="REQUIRED"/>
<tx:method name="*save*" propagation="REQUIRED"/>
<tx:method name="*set*" propagation="REQUIRED"/>
<tx:method name="*update*" propagation="REQUIRED"/>
<tx:method name="*modify*" propagation="REQUIRED"/>
<tx:method name="*change*" propagation="REQUIRED"/>
<tx:method name="*delete*" propagation="REQUIRED"/>
<tx:method name="*drop*" propagation="REQUIRED"/>
<tx:method name="*remove*" propagation="REQUIRED"/>
<tx:method name="*clear*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"></tx:method>
</tx:attributes>
</tx:advice>
<!-- 绑定切面和切入点-->
<aop:config>
<aop:pointcut id="mycut" expression="execution(* com.jv.service.impl.*.*(..))"/>
<!-- 绑定切面-->
<aop:advisor advice-ref="myadvice" pointcut-ref="mycut"></aop:advisor>
</aop:config>
最后
以上就是高挑玉米为你收集整理的Spring框架快速入门Spring的全部内容,希望文章能够帮你解决Spring框架快速入门Spring所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复