切入点的表达式
1. 再配置切入点的时候,需要定义表达式,重点的格式如下:execution(public * *(..)),具体展开如下:
* 切入点表达式的格式如下:
* execution([修饰符] 返回值类型 包名.类名.方法名(参数))
* 修饰符可以省略不写,不是必须要出现的。
* 返回值类型是不能省略不写的,根据你的方法来编写返回值。可以使用 * 代替。
* 包名例如:com.domain.demo3.BookDaoImpl
* 首先com是不能省略不写的,但是可以使用 * 代替
* 中间的包名可以使用 * 号代替
* 如果想省略中间的包名可以使用 ..
* 类名也可以使用 * 号代替,也有类似的写法:*DaoImpl
* 方法也可以使用 * 号代替
* 参数如果是一个参数可以使用 * 号代替,如果想代表任意参数使用 ..
代码演示:
以上一篇文章的结构为例修改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">
<!-- 需spring管理类 -->
<bean id="customerDao" class="demo.CustomerDaoImpl"/>
<!-- 定义切面类 -->
<bean id="AOPXML" class="demo.AOPXML"/>
<!-- 配置AOP -->
<aop:config>
<!-- 引入切面类 切入点+通知类型-->
<aop:aspect ref="AOPXML">
<!--
配置前置通知,方法运行前增强。
pointcut需要写入切入点表达式
表达式意思为,执行到demo.CustomerDaoImpl.demo1方法之前执行增强类
-->
<!-- 切入点表达式的演示 -->
<!-- 普通写法
<aop:before method="demo1" pointcut="execution(public void demo.CustomerDaoImpl.demo1())"/>
-->
<!-- 不写修饰符
<aop:before method="demo1" pointcut="execution(void demo.CustomerDaoImpl.demo1())"/>
-->
<!-- 用*替代返回值,不可不写
<aop:before method="demo1" pointcut="execution(* demo.CustomerDaoImpl.demo1())"/>
-->
<!-- 用*替代类名
<aop:before method="demo1" pointcut="execution(* demo.*.demo1())"/>
-->
<!-- 用*..*替代返包名(可以是多层)与类名
<aop:before method="demo1" pointcut="execution(* *..*.demo1())"/>
-->
<!-- 已demo1开头或结尾的方法
<aop:before method="demo1" pointcut="execution(* *..*.demo1*())"/>
<aop:before method="demo1" pointcut="execution(* *..*.*demo1())"/>
-->
<!-- (..)表示任意参数
<aop:before method="demo1" pointcut="execution(* *..*.*demo1(..))"/>
-->
<aop:before method="demo1" pointcut="execution(* *..*.*demo1(..))"/>
</aop:aspect>
</aop:config>
</beans>
AOP的通知类型
1. 前置通知
* 在目标类的方法执行之前执行。
* 配置文件信息:<aop:after method="before" pointcut-ref="myPointcut3"/>
* 应用:可以对方法的参数来做校验
2. 最终通知
* 在目标类的方法执行之后执行,如果程序出现了异常,最终通知也会执行。
* 在配置文件中编写具体的配置:<aop:after method="after" pointcut-ref="myPointcut3"/>
* 应用:例如像释放资源
3. 后置通知
* 方法正常执行后的通知。
* 在配置文件中编写具体的配置:<aop:after-returning method="afterReturning" pointcut-ref="myPointcut2"/>
* 应用:可以修改方法的返回值
4. 异常抛出通知
* 在抛出异常后通知
* 在配置文件中编写具体的配置:<aop:after-throwing method="afterThorwing" pointcut-ref="myPointcut3"/>
* 应用:包装异常的信息
5. 环绕通知
* 方法的执行前后执行。
* 在配置文件中编写具体的配置:<aop:around method="around" pointcut-ref="myPointcut2"/>
* 要注意:目标的方法默认不执行,需要使用ProceedingJoinPoint对来让目标对象的方法执行。
主要说一下环绕通知,可以用来开启关闭事务。
环绕通知需要自己执行需增强方法,使用ProceedingJoinPoint
- 切面类
package demo;
import org.aspectj.lang.ProceedingJoinPoint;
/**
* 定义AOP切面测试类
* @author Administrator
*
*/
public class AOPXML {
public void demo1() {
System.out.println("AOP测试切面增强类");
}
/**
* #环绕通知测试方法
* @param joinPoint
*/
public void around(ProceedingJoinPoint joinPoint) {
System.out.println("环绕通知1");
//执行目标方法
try {
joinPoint.proceed();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("环绕通知2");
}
}
- 定义环绕通知
<?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">
<!-- 需spring管理类 -->
<bean id="customerDao" class="demo.CustomerDaoImpl"/>
<!-- 定义切面类 -->
<bean id="AOPXML" class="demo.AOPXML"/>
<!-- 配置AOP -->
<aop:config>
<!-- 引入切面类 切入点+通知类型-->
<aop:aspect ref="AOPXML">
<!--
配置前置通知,方法运行前增强。
pointcut需要写入切入点表达式
表达式意思为,执行到demo.CustomerDaoImpl.demo1方法之前执行增强类
<aop:before method="demo1" pointcut="execution(public void demo.CustomerDaoImpl.demo1())"/>
-->
<!-- 环绕通知 -->
<aop:around method="around" pointcut="execution(public void demo.CustomerDaoImpl.demo1())"/>
</aop:aspect>
</aop:config>
</beans>
- 测试类
package demo;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* 依然通过整合junit4来实现测试类
* @author Administrator
*
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class AOPDemo {
//注解的方式获得bean,无需提供setter方法
@Resource(name="customerDao")
private CustomerDao cdao;
@Test
public void run1() {
cdao.demo1();
}
}
- 执行结果