AspectJ是一个基于java的aop框架。
切入点表达式: execution() 用于描述方法
语法: execution(修饰符 返回值 包.类.方法名(参数) throws 异常)
切面类:
package com.atchina.d_spring_aop_xml;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspect {
public void before(JoinPoint joinPoint){
System.out.println("aspect xml 事务开启 before "+joinPoint.getSignature().getName());
}
public void after(JoinPoint joinPoint, Object ret){
System.out.println("aspect xml 事务开启 after "+joinPoint.getSignature().getName()+", -->"+ret);
}
public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("环绕通知,在目标方法之前...增强功能");
// 手动执行目标方法
Object obj = joinPoint.proceed();
if(null !=obj){
// 修改目标方法的执行结果
obj = "update";
}
System.out.println("环绕通知,在目标方法之后...增强功能");
return obj;
}
public void myThrowing(JoinPoint joinPoint, Throwable e){
System.out.println("aspect xml 异常通知. "+joinPoint.getSignature().getName()+", 异常通知信息"+e.getMessage());
}
public void myAfter(JoinPoint joinPoint){
System.out.println("aspect xml 最终通知 "+joinPoint.getSignature().getName());
}
}
接口
public interface UserService {
void addUser();
String updateUser();
}
public class UserServiceImpl implements UserService {
@Override
public void addUser() {
System.out.println("config adduser...");
}
@Override
public String updateUser() {
System.out.println("config updateUser...");
// int i = 1/0; // 测试异常通知
return "updateUserRet";
}
}
配置文件
<?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">
<!-- 1.创建目标类 -->
<bean id="userService" class="com.atchina.d_spring_aop_xml.UserServiceImpl"/>
<!-- 2.创建切面类 -->
<bean id="myAspectId" class="com.atchina.d_spring_aop_xml.MyAspect"/>
<!-- 3. aop编程
使用<aop:config>配置
<aop:aspect> 将切面类声明"切面",从而获得通知方法
ref:切面类引用
<aop:pointcut> 声明一个切入点,所有的通知都可以使用
expression:切入点表达式
id:名称, 用于其他通知引用
-->
<aop:config>
<aop:aspect ref="myAspectId">
<aop:pointcut expression="execution(* com.atchina.d_spring_aop_xml.UserServiceImpl.*(..))" id="myPointCut" />
<!-- 前置通知
method: 通知,及方法名
pointcut: 切入点表达式,此表达式只能在当前通知中使用。
pointcut-ref: 切入点引用,可以与其他通知共享切入点
通知方法格式:public void before(JoinPoint joinPoint)
参数1:org.aspectj.lang.JoinPoint 用于描述连接点(目标方法),获得目标方法名等
<aop:before method="before" pointcut-ref="myPointCut"/>
-->
<!-- 后置通知
method: 通知,及方法名
pointcut: 切入点表达式,此表达式只能在当前通知中使用。
pointcut-ref: 切入点引用,可以与其他通知共享切入点
returning: 通知方法第二个参数的名称
通知方法格式:public void after(JoinPoint joinPoint, Object ret)
参数1:org.aspectj.lang.JoinPoint 用于描述连接点(目标方法),获得目标方法名等
参数2:类型Object, 参数名returning="ret"配置的
如下:
<aop:after-returning method="after" pointcut-ref="myPointCut" returning="ret"/>
-->
<!-- 环绕通知
method: 通知,及方法名
pointcut: 切入点表达式,此表达式只能在当前通知中使用。
pointcut-ref: 切入点引用,可以与其他通知共享切入点
通知方法格式:public Object around(ProceedingJoinPoint joinPoint) throws Throwable
返回值类型: Object
方法名: 任意
参数: org.aspectj.lang.ProceedingJoinPoint
抛出异常:
执行目标方法: Object obj = joinPoint.proceed();
如下:
<aop:around method="around" pointcut-ref="myPointCut"/>
-->
<!-- 异常通知
method: 通知,及方法名
pointcut: 切入点表达式,此表达式只能在当前通知中使用。
pointcut-ref: 切入点引用,可以与其他通知共享切入点
throwing: 通知方法第二个参数的名称
通知方法格式:public void myThrowing(JoinPoint joinPoint, Throwable e)
参数1:org.aspectj.lang.JoinPoint 用于描述连接点(目标方法),获得目标方法名等
参数2:类型throwing, 参数名throwing="e"配置的
如下:
<aop:after-throwing method="myThrowing" pointcut-ref="myPointCut" throwing="e"/>
-->
<!-- 最终通知
-->
<aop:after method="myAfter" pointcut-ref="myPointCut" />
</aop:aspect>
</aop:config>
</beans>
测试类
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestFactoryBean {
@Test
public void test(){
String xmlPath = "com/atchina/d_spring_aop_xml/applicationContext.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService)ac.getBean("userService");
userService.addUser();
String ret = userService.updateUser();
System.out.println(ret);
}
}