package com.li.utils;
/*
* 用于提供日志的工具类,抽取公共代码
* */
public class Logger {
/**
* @Description: 打印日志,在切入点方法执行之前进行
* @Param:
* @return:
* @Date: 2020/5/14
*/
public void printLog(){
System.out.println("开始记录日志了");
}
}
package com.li.aop;
public class AccountServiceImpl implements AccountService {
public void safeCount() {
System.out.println("账户存储");
}
public void createCount(int i) {
System.out.println("新建账户");
}
public int deleteCount() {
System.out.println("删除账户");
return 0;
}
}
<bean id="accountService" class="com.li.aop.AccountServiceImpl"></bean>
<!--配置通知bean-->
<bean id="logger" class="com.li.utils.Logger"></bean>
<!--切入点表达式的写法:
关键字:execution(表达式)
表达式:
访问修饰符 返回值 包名.包名.包名...类名.方法名(参数列表)
标准的表达式写法:
public void com.li.service.impl.AccountServiceImpl.saveAccount()
1)访问修饰符可以省略
2)返回值可以使用通配符,表示任意返回值
3)包名可以使用通配符,表示任意包。但是有几级包,就需要写几个*.
4)包名可以使用..表示当前包及其子包
5)类名和方法名都可以使用*来实现通配
* *..*.*()
6)参数列表:
可以直接写数据类型:
基本类型直接写名称 int
引用类型写包名.类名的方式 java.lang.String
可以使用通配符表示任意类型,但是必须有参数
可以使用..表示有无参数均可,有参数可以是任意类型
全通配写法:
* *..*.*(..)
实际开发中切入点表达式的通常写法:
切到业务层实现类下的所有方法
* com.li.service.impl.*.*(..)
-->
<bean id="logger" class="com.li.utils.Logger"></bean>
<aop:config>
<aop:aspect id="logAdvice" ref="logger">
<aop:before method="printLog" pointcut="execution(public void com.li.aop.AccountServiceImpl.safeCount())"></aop:before>
</aop:aspect>
</aop:config>
package com.li.utils;
/*
* 用于提供日志的工具类,抽取公共代码
* */
public class Logger {
/**
* @Description: 打印日志,在切入点方法执行之前进行
* @Param:
* @return:
* @Author: Mr.Wang
* @Date: 2020/5/14
*/
//前置通知
public void beforePrintLog(){
System.out.println("前置通知开始记录日志了");
}
//后置通知
public void afterReturningPrintLog(){
System.out.println("后置通知记录日志了");
}
//异常通知
public void afterThrowingPrintLog(){
System.out.println("异常通知开始记录日志了");
}
//最后通知
public void afterPrintLog(){
System.out.println("最后通知开始记录日志了");
}
}
<bean id="logger" class="com.li.utils.Logger"></bean>
<aop:config>
<aop:aspect id="logAdvice" ref="logger">
<aop:before method="beforePrintLog" pointcut-ref="service"></aop:before>
<aop:after-returning method="afterReturningPrintLog" pointcut-ref="service"></aop:after-returning>
<aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="service"></aop:after-throwing>
<aop:after method="afterPrintLog" pointcut-ref="service"></aop:after>
<aop:pointcut id="service" expression="execution(* com.li.aop.*.*(..))"></aop:pointcut>
</aop:aspect>
</aop:config>
如果环绕通知方法仅如下编写,则运行时不会运行切入点。
public void arroundPrintLog(){
System.out.println("环绕通知开始记录日志了");
}
<aop:around method="arroundPrintLog" pointcut-ref="service"></aop:around>
public Object arroundPrintLog(ProceedingJoinPoint point){
Object rtvalue = null;
try {
Object[] args = point.getArgs();//得到方法执行所需的参数
System.out.println("前置通知开始记录日志了");
rtvalue = point.proceed(args);
System.out.println("后置通知记录日志了");
return rtvalue;
} catch (Throwable throwable) {
System.out.println("异常通知开始记录日志了");
throw new RuntimeException(throwable);
}finally {
System.out.println("最终通知开始记录日志了");
}
}
package com.li.utils;
import com.li.aop.AccountServiceImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
/*
* 用于提供日志的工具类,抽取公共代码
* */
@Configuration
@Import(AccountServiceImpl.class)
@EnableAspectJAutoProxy
@Component("logger")
@Aspect
public class Logger {
@Pointcut("execution(* com.li.aop.*.*(..))")
private void serviceMethod(){};
/* //前置通知
@Before("serviceMethod()")
public void beforePrintLog(){
System.out.println("前置通知开始记录日志了");
}
//后置通知
@AfterReturning("serviceMethod()")
public void afterReturningPrintLog(){
System.out.println("后置通知记录日志了");
}
//异常通知
@AfterThrowing("serviceMethod()")
public void afterThrowingPrintLog(){
System.out.println("异常通知开始记录日志了");
}
//最后通知
@After("serviceMethod()")
public void afterPrintLog(){
System.out.println("最后通知开始记录日志了");
}*/
//环绕通知
@Around("serviceMethod()")
public Object arroundPrintLog(ProceedingJoinPoint point){
Object rtvalue = null;
try {
Object[] args = point.getArgs();//得到方法执行所需的参数
System.out.println("前置通知开始记录日志了");
rtvalue = point.proceed(args);
System.out.println("后置通知记录日志了");
return rtvalue;
} catch (Throwable throwable) {
System.out.println("异常通知开始记录日志了");
throw new RuntimeException(throwable);
}finally {
System.out.println("最终通知开始记录日志了");
}
}
}
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- yrrf.cn 版权所有 赣ICP备2024042794号-2
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务