上代码:
注入一个Aop切面类:
package cn.cdulm.aspects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Arrays;
@Aspect // 标记为切面
@Component // 标记为Bean组件,进入Ioc容器,才能切入Bean
public class LogAspects {
@Pointcut("execution(* cn.cdulm.service.impl.*.*(..))")
public void pointcut() {
}
// 前置通知
@Before("pointcut()")
public void before() {
System.out.println("before - 前置通知");
}
// 后置通知
@After("pointcut()")
public void after() {
System.out.println("after - 后置通知");
}
// 后置异常通知
@AfterThrowing("pointcut()")
public void afterThrowing() {
System.out.println("afThrow - 后置异常通知");
}
// 后置返回通知
@AfterReturning("pointcut()")
public void afterReturning() {
System.out.println("return - 后置返回通知");
}
// 环绕通知
@Around("pointcut()")
public Object around(ProceedingJoinPoint joinPoint) {
// 获取方法名
String methodName = joinPoint.getSignature().getName();
// 所有的参数
Object[] args = joinPoint.getArgs();
Object res = null;
try {
System.out.println("Around - 前置通知:" + methodName + " 方法执行,参数:" + Arrays.asList(args));
res = joinPoint.proceed();
System.out.println("Around - 后置通知:" + methodName + " 方法执行,参数:" + Arrays.asList(args));
} catch (Throwable e) {
System.out.println("Around - 异常通知:" + e);
} finally {
System.out.println("Around - 返回通知:" + res);
}
return res;
}
}
从execution(* cn.cdulm.service.impl.*.*(..)) 查看切入的包、类和方法:
可以发现切入的是cn.cdulm.service.impl包下所有的类及方法:
只有UserServiceImpl类:
package cn.cdulm.service.impl;
import cn.cdulm.dao.IUserDao;
import cn.cdulm.entity.User;
import cn.cdulm.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
IUserDao userDao;
@Override
public User select(Integer id) throws Exception {
System.out.println("查询");
// throw new RuntimeException("抛异常啦!");
return userDao.select(id);
}
@Override
public void add(User user) throws Exception {
System.out.println("添加");
userDao.add(user);
}
@Override
public void delete(Integer id) throws Exception {
System.out.println("删除");
userDao.delete(id);
}
@Override
public void update(User user) throws Exception {
System.out.println("更改");
userDao.update(user);
}
}
测试方法:
package cn.cdulm.test;
import cn.cdulm.entity.User;
import cn.cdulm.service.IUserService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IocTest {
@Test
public void f1() throws Exception {
ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("classpath:/springIoc.xml");
IUserService bean = ioc.getBean(IUserService.class);
// System.out.println(bean.getClass());
User s = bean.select(112);
// 没有使用切面结果:class cn.cdulm.service.impl.UserServiceImpl
/* 使用切面后结果:class com.sun.proxy.$Proxy20 jdk生成的动态代理类
当类实现了接口会默认由jdk的方式生成代理类
当类没有实现接口会默认由CGLIB的方式生成代理类
*/
}
}
输出结果:
1 2 3 4 5 6 7 | Around - 前置通知:select 方法执行,参数:[ 112 ] before - 前置通知 查询 return - 后置返回通知 after - 后置通知 Around - 后置通知:select 方法执行,参数:[ 112 ] Around - 返回通知:cn.cdulm.entity.User @be35cd9 |
现在将UserServiceImpl中的异常注释打开:
运行结果:
1 2 3 4 5 6 7 | Around - 前置通知:select 方法执行,参数:[ 112 ] before - 前置通知 查询 afThrow - 后置异常通知 after - 后置通知 Around - 异常通知:java.lang.RuntimeException: 抛异常啦! Around - 返回通知: null |
由此可以看出@Around环绕通知是五大通知里面功能最全最强的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)