文章目录
一、环境搭建
(1)准备必要的代码
实体类Person
package com.gql.entity;
/**
* 类说明:
* Person实体类
* @guoqianliang1998.
*/
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
接口PersonDao
package com.gql.aop;
import com.gql.entity.Person;
/**
* 类说明:
* 接口
* @guoqianliang1998.
*/
public interface PersonDao {
void save(Person person);
}
目标类/实现类PersonDaoImp
package com.gql.aop;
import com.gql.entity.Person;
/**
* 类说明:
* 目标类
* @guoqianliang1998.
*/
public class PersonDaoImp implements PersonDao {
@Override
public void save(Person person) {
//自定义异常
//int i=1/0;
System.out.println("保存Person成功...");
}
}
XML配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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/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 ">
<!-- 目标类 -->
<bean id="personDao" class="com.gql.aop.PersonDaoImp"></bean>
<!-- 切面 -->
<bean id="m" class="com.gql.transaction.MyTransaction"></bean>
<!-- AOP配置 -->
<aop:config>
<!-- 切入点表达式配置 -->
<aop:pointcut expression="execution (* com.gql.aop.PersonDaoImp.*(..))" id="point"/>
<!-- 切面配置 -->
<aop:aspect ref="m">
<!-- 前置通知 -->
<aop:before method="begin" pointcut-ref="point"/>
<!-- 后置通知 -->
<aop:after-returning method="commit" pointcut-ref="point"/>
<!-- 异常通知 -->
<aop:after-throwing method="ex" pointcut-ref="point" throwing="e"/>
<!-- 最终通知 -->
<aop:after method="finall" pointcut-ref="point"/>
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
</beans>
(2)准备必要的jar包
(3)创建Spring的配置文件并导入约束
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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/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 ">
</beans>
(4)配置Spring的ioc
<!-- 配置目标类 -->
<bean id="personDao" class="com.gql.aop.PersonDaoImp"></bean>
(5)抽取公共代码制作成通知MyTransaction
package com.gql.transaction;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 类说明:
* 事务类
* @guoqianliang1998.
*/
public class MyTransaction {
public void begin(){
System.out.println("开启事务...");
}
public void commit(){
System.out.println("提交事务...");
}
public void ex(Throwable e){
System.out.println(e.getMessage());
System.out.println("出现异常...");
}
public void finall(){
System.out.println("最终通知...");
}
public void around(ProceedingJoinPoint p ) throws Throwable{
System.out.println("环绕通知前...");
p.proceed();//放行,执行目标方法
System.out.println("环绕通知后...");
}
}
二、配置步骤
(1)配置通知类
<!-- 配置切面 -->
<bean id="m" class="com.gql.transaction.MyTransaction"></bean>
(2)aop:config声明 aop 配置
aop:config标签
- 作用:用于声明开始 aop 的配置。
<aop:config>
配置的代码都写在此处
</aop:config>
(3)aop:aspect配置切面
aop:aspect标签
- 作用:用于配置切面。
- 属性:id:给切面提供一个唯一标识;ref:引用配置好的通知类 bean 的 id
<!-- 切面配置 -->
<aop:aspect ref="m">
配置通知的类型要写在此处
</aop:aspect>
(4)aop:pointcut配置切入点表达式
aop:pointcut标签
- 作用:用于配置切入点表达式。就是指定对哪些类的哪些方法进行增强。
- 属性:expression:用于定义切入点表达式;id:用于给切入点表达式提供一个唯一标识。
<!-- 切入点表达式配置 -->
<aop:pointcut expression="execution (* com.gql.aop.PersonDaoImp.*(..))" id="point"/>
(5)配置对应的通知类型
①aop:before前置通知
- 作用:用于配置前置通知。指定增强的方法在切入点方法之前执行。
- 属性:method:用于指定通知类中的增强方法名称;ponitcut-ref:用于指定切入点的表达式的引用;poinitcut:用于指定切入点表达式。
- 执行时间点:切入点方法执行之前执行。
<!-- 前置通知 -->
<aop:before method="begin" pointcut-ref="point"/>
②aop:after-returning后置通知
- 作用:用于配置后置通知。
- 属性:method:指定通知中方法的名称;pointct:定义切入点表达式;pointcut-ref:指定切入点表达式的引用。
- 执行时间点:切入点方法正常执行之后。它和异常通知只能有一个执行。
- 注意:通过returning标签可以得到返回值。
<!-- 后置通知 -->
<aop:after-returning method="commit" pointcut-ref="point"/>
③aop:after-throwing异常通知
- 作用:用于配置异常通知。
- 属性:method:指定通知中方法的名称;pointct:定义切入点表达式;pointcut-ref:指定切入点表达式的引用。
- 执行时间点:
切入点方法执行产生异常后执行。它和后置通知只能执行一个。
<!-- 异常通知 -->
<aop:after-throwing method="ex" pointcut-ref="point" throwing="e"/>
④aop:after最终通知
- 作用:用于配置最终通知。
- 属性:method:指定通知中方法的名称;pointct:定义切入点表达式;pointcut-ref:指定切入点表达式的引用。
- 执行时间点:无论切入点方法执行时是否有异常,它都会在其后面执行。
<!-- 最终通知 -->
<aop:after method="finall" pointcut-ref="point"/>
⑤aop:around环绕通知
aop:around
- 作用:用于配置环绕通知。
- 属性:method:指定通知中方法的名称;pointct:定义切入点表达式;pointcut-ref:指定切入点表达式的引用。
- 说明:它是 spring 框架为我们提供的一种可以在代码中手动控制增强代码什么时候执行的方式。
- 注意:通常情况下,环绕通知都是独立使用的。
<!-- 环绕通知 -->
<aop:around method="around" pointcut-ref="point"/>