学习目标

  • (1)SpringAOP
  • (2)事务
  • (3)Spring事务管理
  • (4)Spring和Mybatis整合

动态代理JDK proxy

(1)动态代理,必须要有一个接口 com.wzx.demo01
(2)动态代理的三个参数
代理类,与被代理类 地位是一样的
(相同的ClassLoader,相同的接口)
所以,有相同的接口,相同的类加载器
(3)invoke方法
参2 表示要增强哪个方法
​​​Object returnValue = method.invoke(laoZong,args);​

AOP的术语

1、 目标类target:就是我们需要增强的那个类 LaoZong.class
2、 代理类proxy:就是自定义的代理的对象 $Proxy0.class
3、 连接点joinPoint:程序执行的某个特定位置,Spring仅支持方法的连接点
eat(),sleep(),run()
4、 切入点pointCut:就是在目标类中实际增强的方法
eat()
5、 织入weave:就是将代理类中需要增强的方法放入到目标类中去执行的过程
将原方法与其他类的方法一起调用
6、 引介Introduction:引介是一种特殊的增强,它为类添加一些属性和方法(课程不使用)
7、 通知advice:将代理对象中的方法应用到目标类的过程中产生的结果。
8、 切面aspect:所有的切入点和代理对象的方法组成在一起 构成了切面

Spring AOP的准备

pom.xml

<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.2</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>

</dependencies>

IUser

//1 必须要有一个接口
public interface IUser {
void work();
}

UserImpl

//2 类与接口是实现关系
public class UserImpl implements IUser {
//连接点
//切点
@Override
public void work() {
System.out.println("我加班我快乐");
}
}

Advice

public class Advice {
public void writeLog(){
System.out.println("写一个开发备忘录");
}
}

Spring AOP的Xml配置

Day23SSM之Spring AOP***_xml

applicationContext.xml

<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">


<!-- 创建UserImpl对象 目标类 -->
<bean id="userImpl" class="com.wzx.service.impl.UserImpl"/>
<!-- 创建Advice对象-->
<bean id="advice" class="com.wzx.service.Advice"/>
<!-- 配置他们的增强关系 生成一个代理类-->
<aop:config >
<aop:pointcut id="work" expression="execution(public void com.wzx.service.impl.UserImpl.work())"/>
<!-- 我想在work方法执行 之后调用一下writeLog-->
<aop:aspect ref="advice">
<aop:after method="writeLog" pointcut-ref="work"/>
</aop:aspect>
</aop:config>
</beans>

UserImplTest

public class UserImplTest {

@Autowired
IUser iUser;
@Test
public void work() {
System.out.println(iUser);
iUser.work();;
}
}

AOP切面编程-切面表达式

  • (1)什么是切面表达式
    ​​​execution([修饰符] 返回值类型 包.类.方法(参数列表) );​
  • (2)切面表达式有什么用?
    符合表达式的方法,会被增强
    使用* 表过任意的内容
    使用… 可以表示包与子包下面的类
    使用…可以写在方法(…)表示任意参数
<!--    配置他们的增强关系 生成一个代理类-->
<aop:config >
<aop:pointcut id="work" expression="execution(* com.wzx.service..*.*(..))"/>
<!-- 我想在work方法执行 之后调用一下writeLog-->
<aop:aspect ref="advice">
<aop:after method="writeLog" pointcut-ref="work"/>
</aop:aspect>
</aop:config>

AOP切面编程-增强方式

(1)增强方式的方式有哪些?

实质是增强的四个可选调用位置

Day23SSM之Spring AOP***_spring_02

(2)每个位置有四个对应的名称
(3)arround环绕
简化
​​​joinPoint.proceed(); //切到原来的目标方法,进行执行​

Advice

public class Advice {
public void writeLog(){
System.out.println("写一个开发备忘录");
}
public void before(){
System.out.println("before-------");
}
public void after(){
System.out.println("after-------");
}
public void afterReturn(){
System.out.println("afterReturn-------");
}
public void afterThrow(){
System.out.println("afterThrow-------");
}
}

applicationContext.xml

<!--    配置他们的增强关系 生成一个代理类-->
<aop:config >
<aop:pointcut id="all" expression="execution( * com.wzx.service..*.*(..))"/>
<!-- 我想在work方法执行 之后调用一下writeLog-->
<aop:aspect ref="advice">
<!-- try-->
<aop:before method="before" pointcut-ref="all"/>
<!-- 有可能程序正常运行-->
<aop:after-returning method="afterReturn" pointcut-ref="all"/>
<!-- catch-->
<aop:after-throwing method="afterThrow" pointcut-ref="all"/>
<!-- finally-->
<aop:after method="after" pointcut-ref="all"/>

</aop:aspect>
</aop:config>

环绕通知

Advice

public void arround(ProceedingJoinPoint point ){//参目标类中的任意方法
try{
//执行before
before();
System.out.println("arround-------");
point.proceed();//对应你调用的UserImpl中的任意方法
//执行正常返回
afterReturn();
}catch (Throwable e){
//补救方法
afterThrow();
}finally {
//释放资源的方法
after();
}
}

applicationContext.xml

<!--    配置他们的增强关系 生成一个代理类-->
<aop:config >
<aop:pointcut id="all" expression="execution( * com.wzx.service..*.*(..))"/>
<!-- 我想在work方法执行 之后调用一下writeLog-->
<aop:aspect ref="advice">

<aop:around method="arround" pointcut-ref="all"/>

</aop:aspect>
</aop:config>

AOP切面编程-注解***

(1)spring注解配置
一个xml开启注解自动代理
几个注解

  • 切面@Aspect+四个注解 @Before @AfterReturning @AfterThrowing@After
  • 切面@Aspect+@Arround

Advice

@Component
@Aspect
public class Advice {
public void writeLog(){
System.out.println("写一个开发备忘录");
}
//try{ }
// @Before("execution( * com.wzx.service..*.*(..))")
public void before(){
System.out.println("before-------");
}
//@AfterReturning("execution( * com.wzx.service..*.*(..))")
public void afterReturn(){
System.out.println("afterReturn-------");
}
//catch(exception e){ }
// @AfterThrowing("execution( * com.wzx.service..*.*(..))")
public void afterThrow(){
System.out.println("afterThrow-------");
}
//finally
// @After("execution( * com.wzx.service..*.*(..))")
public void after(){
System.out.println("after-------");
}

@Around("execution( * com.wzx.service..*.*(..))")
public void arround(ProceedingJoinPoint point ){//参目标类中的任意方法
try{
//执行before
before();
System.out.println("arround-------");
point.proceed();
//执行正常返回
afterReturn();
}catch (Throwable e){
//补救方法
afterThrow();
}finally {
//释放资源的方法
after();
}
}
}

applicationContext.xml

<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--包扫描创建对象 扫描包与它下面的子包中的所有类-->
<context:component-scan base-package="com.wzx.service"/>

<!--开启自动AOP代理-->
<aop:aspectj-autoproxy/>

</beans>