快速入门
1.
导入
AOP
相关坐标
2.
创建目标接口和目标类(内部有切点)
3.
创建切面类(内部有增强方法)
4.
将目标类和切面类的对象创建权交给
spring
5.
在
applicationContext.xml
中配置织入关系
6.
测试代码
项目结构:
AccountService 创建目标接口
package wwx.aop;
public interface AccountService {
public void save();
//AccountService,Spring,AOPTest,AccountServiceImpl,MyAspect
}
AccountServiceImpl 创建目标类
package wwx.aop;
//目标类
public class AccountServiceImpl implements AccountService {
@Override
public void save() {
System.out.println("save方法执行了。。。");
int num=10/0;//0不能作分母,有异常,异常通知才会执行
}
}
MyAspect 创建切面类(内部有增强的方法)
package wwx.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import java.util.Date;
//切面类
public class MyAspect {
//前置通知
public void before() {
Date date = new Date();
System.out.println("前置通知:"+date);
}
//后置通知
public void afterreturning(){
System.out.println("后置通知:方法执行完毕");
}
//环绕通知
public void around(ProceedingJoinPoint joinPoint) throws Throwable {
//记录方法执行的时间
long time01 = System.currentTimeMillis();
System.out.println("方法执行前");
//切入点方法执行
joinPoint.proceed();
//记录方法执行后的时间
long time2 = System.currentTimeMillis();
System.out.println("方法执行后");
//后-前
System.out.println("环绕通知:方法执行的时间"+(time2-time01));
}
//异常通知
public void throwing(){
System.out.println("异常通知:系统升级中...");
}
//最终通知
public void after(){
System.out.println("最终通知:我一定会执行");
}
}
Spring 将目标类和切面类的对象创建权交给 spring,在 spring配置文件中配置织入关系
<?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
">
<!--配置目标类-->
<bean id="accountService" class="wwx.aop.AccountServiceImpl"></bean>
<!--配置切面类-->
<bean id="myAspect" class="wwx.aop.MyAspect"></bean><!--这行,是把创建切面类的权利交给Spring-->
<!--私有方法一旦执行,spring就会监听到,一旦监听到就会根据类的接口
去整一个代理对象,然后根据通知的类型,去对私有方法进行增强
-->
<!--配置aop的织入-->
<aop:config>
<!--配置切面:切入点+通知-->
<aop:aspect ref="myAspect"><!--指定myAspect作为切面类-->
<!--第1种织入方式-->
<!--前置通知-->
<aop:before method="before" pointcut="execution(public void wwx.aop.AccountServiceImpl.save())"></aop:before>
<!--后置通知-->
<aop:after-returning method="afterreturning" pointcut-ref="pt1"></aop:after-returning>
<!--第2种织入方式-->
<aop:pointcut id="pt1" expression="execution(public void
wwx.aop.AccountServiceImpl.save())"/>
<!--环绕通知-->
<aop:around method="around" pointcut-ref="pt1"></aop:around>
<!--异常通知-->
<aop:after-throwing method="throwing" pointcut-ref="pt1"></aop:after-throwing>
<!--最终通知-->
<aop:after method="after" pointcut-ref="pt1"></aop:after>
</aop:aspect>
</aop:config>
</beans>
AOPTest 测试代码
package wwx.aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AOPTest {
@Test
public void test01()
{
//加载配置文件
ApplicationContext app = new ClassPathXmlApplicationContext("Spring.xml");
//获得Bean
AccountService accountService = (AccountService) app.getBean("accountService");
//执行方法
accountService.save();
}
}
目标类中有异常时:
目标类中无异常时:
2.2
切点表达式的写法
表达式语法:
execution ([ 修饰符 ] 返回值类型 包名 . 类名 . 方法名 ( 参数 ))
访问修饰符可以省略
返回值类型、包名、类名、方法名可以使用星号
*
代表任意
包名与类名之间一个点
.
代表当前包下的类,两个点
..
表示当前包及其子包下的类
参数列表可以使用两个点
..
表示任意个数,任意类型的参数列表
execution ( public void com . lzw . aop . Service . method ())execution ( void com . lzw . aop . Service . * (..))execution ( * com . lzw . aop . * . * (..))execution ( * com . lzw . aop .. * . * (..))execution ( * * .. * . * (..))
2.3
通知的类型
通知的配置语法:
< aop : 通知类型 method = “ 切面类中方法名 ” pointcut = “ 切点表达式 "></aop: 通知类型 >