本人学习历程,参考性不强、
介绍两种AOP实现方式(XML和注解模式)
首先要有对应的服务接口以及实际服务,切面类
BaseService接口;service类,aspect类(包含相应的新增方法)
1.注解方式实现AOP
首先,将service使用注解方式介绍个给pring容器对象 @Component(),
别忘了在spring核心配置文件中给出组件扫描器:
<context:component-scan base-package="位置"/>
然后,service就不需要改动了(符合代理设计模式的理念。)
然后,在Aspect类中书写注解:
@Aspect @Component("aspect") public class MyAspect { //代理类与切面类需要实现相同的接口 //功能要求:打印时间 @AfterReturning(value = "execution( * com.bjpowernode.service.BaseService.ser*(..) )") public void endTime(){ System.out.println("目标方法运行结束时间 "+ new Date()); } @Before("pt()") public void startTime(){ System.out.println("目标方法运行开始时间: "+new Date()); } @AfterThrowing() public void exceptionTime(){ System.out.println("当前目标方法发生错误时间"+new Date()); } @After("pt()") public void afterTime(){ System.out.println("最终返回时间"+new Date()); } @Around("pt()") public void around(ProceedingJoinPoint point) throws Throwable{ System.out.println("环绕方法开始时间"+new Date()); point.proceed(); System.out.println("环绕方法结束时间"+new Date()); } @Pointcut() public void pt(){ } }
解释:
(1)@Aspect @Component("aspect")。
注解介绍:@Aspect表明为切面类,
@Component("aspect")可写可不写。写了主要是区分类
其中,如果使用注解@Aspect,在xml文件中得给出介绍:(跟组件扫描器作用类似)
<aop:aspectj-autoproxy/>
(2)
@Pointcut(value = "execution(* com.bjpowernode.service.BaseService.ser*(..))") public void pt(){} 切入点,在该注解下的方法被视为切入点的载体,五种通知通过获取方法名来获取到切入点。方法本身下的内容应为空体,返回void。
tip:五种通知既可以在自己的字段内书写切入点表达式来获取切入点,也可以通过@Pointcut来获取。
比如:
@AfterReturning(value = "execution( * com.bjpowernode.service.BaseService.ser*(..) )")
@Before("pt()")
@Pointcut(value = "execution(* com.bjpowernode.service.BaseService.ser*(..))") public void pt(){
(3)
@Before(……) 前置通知,在服务方法前输出内容
@AfterReturning(……)后置通知,在服务方法后输出
@AfterThrowing(……)异常通知,当前服务方法发生异常时输出
@After(……)最终通知,无论如何最后输出,(异常发生也会输出,在异常通知和后置通知后)
@Around("pt()") public void around(ProceedingJoinPoint point) throws Throwable{ System.out.println("环绕方法开始时间"+new Date()); point.proceed(); System.out.println("环绕方法结束时间"+new Date()); } 环绕通知:连接点前后输出(说白了,就是获取到当前执行流程,由around指定的方法内执行前输出,再调用增强的方法,再执行后输出,实现前后的输出)
2.Xml文件方式实现AOP
比较繁琐,大体如图,可以有多个切入点,可以有多个通知。
一般使用注解,比较好理解,Xml中写会很繁琐
切入点表达式的理解:
在Xml文件中的<aop:config>……</aop:config>中写
<aop:pointcut id="pt1" expression="execution(public void com.bjpowernode.serviceImpl.*.service1())"/>
在注解中写:
@AfterReturning(value = "execution( * com.bjpowernode.service.BaseService.ser*(..) )")
@Pointcut(value = "execution(* com.bjpowernode.service.BaseService.ser*(..))")
execution()括号里的内容有四部分:
权限符(public private之类)+ 返回类型(void,String,Object)+ 指定方法路径(位置)+ 方法名称以及参数
其中返回类型和方法名(包参数)是必写的,权限符和路径不是必要的。
指定符: * : 0~任意字符
.. : 为任意数量,任意类型字符
+:用于路径下的指定,添加多个不同路径下的方法
示例:
execution(* join(String, *))join的方法,首参为String,次参为任意类型
(* join(String, ..)) 首参为String,后面任意数量,任意类型参数