AOP通知获取数据
- AOP通知获取参数
- 非环绕通知获取参数方式
- 环绕通知获取参数方式
- AOP通知获取返回值
- 环绕通知获取返回值
- 返回后通知获取返回值
- AOP通知获取数据的案例
AOP通知获取参数
非环绕通知获取参数方式
在方法上添加JoinPoint,通过JoinPoint来获取参数, 这里只使用前置通知当做例子,其他都是一样的。
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(* com.itheima.dao.BookDao.findName(..))")
private void pt(){}
@Before("pt()")
public void before(JoinPoint jp)
// 使用JoinPoint调用getArgs方法获取参数信息
Object[] args = jp.getArgs();
System.out.println(Arrays.toString(args));
System.out.println("before advice ..." );
}
}
说明:
使用JoinPoint的方式获取参数适用于前置
、后置
、返回后
、抛出异常后
通知。这里只举例了前置通知
类型。
环绕通知获取参数方式
环绕通知使用的是ProceedingJoinPoint,因为ProceedingJoinPoint是JoinPoint类的子类,所以对于ProceedingJoinPoint类中应该也会有对应的getArgs()
方法。
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(* com.itheima.dao.BookDao.findName(..))")
private void pt(){}
@Around("pt()")
public Object around(ProceedingJoinPoint pjp)throws Throwable {
Object[] args = pjp.getArgs();
System.out.println(Arrays.toString(args));
Object ret = pjp.proceed();
return ret;
}
}
AOP通知获取返回值
对于返回值,只有返回后AfterReturing
和环绕Around
这两个通知类型可以获取,具体获取方式如下
环绕通知获取返回值
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(* com.itheima.dao.BookDao.findName(..))")
private void pt(){}
@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable{
Object[] args = pjp.getArgs();
System.out.println(Arrays.toString(args));
args[0] = 666;
// 获取原始方法返回值,如果有需要还可以对返回值ret进行修改
Object ret = pjp.proceed(args);
return ret;
}
//其他的略
}
返回后通知获取返回值
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(* com.itheima.dao.BookDao.findName(..))")
private void pt(){}
@AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(Object ret) {
System.out.println("afterReturning advice ..."+ret);
}
//其他的略
}
注意:
(1) 参数名的问题
(2) afterReturning方法参数类型的问题
参数类型可以写成String,但是为了能匹配更多的参数类型,建议写成Object类型
(3) afterReturning方法参数的顺序问题
AOP通知获取数据的案例
需求: 对百度网盘分享链接输入密码时尾部多输入的空格做兼容处理。
-
创建一个Maven项目
-
pom.xml添加Spring依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
- 添加ResourcesService,ResourcesServiceImpl,ResourcesDao和ResourcesDaoImpl类
public interface ResourcesDao {
boolean readResources(String url, String password);
}
@Repository
public class ResourcesDaoImpl implements ResourcesDao {
public boolean readResources(String url, String password) {
//模拟校验
return password.equals("root");
}
}
public interface ResourcesService {
public boolean openURL(String url ,String password);
}
@Service
public class ResourcesServiceImpl implements ResourcesService {
@Autowired
private ResourcesDao resourcesDao;
public boolean openURL(String url, String password) {
return resourcesDao.readResources(url,password);
}
}
- 创建Spring的配置类
@Configuration
@ComponentScan("com.itheima")
@EnableAspectJAutoProxy
public class SpringConfig {
}
- 编写通知类并添加环绕通知
@Component
@Aspect
public class MyAdvice {
@Pointcut("execution(* com.itheima.service.ResourcesService.openURL(String, String))")
private void servicePt(){}
@Around("servicePt()")
public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
Object[] args = pjp.getArgs();
System.out.println("去除空格前参数信息:" + Arrays.toString(args));
// 去除参数两端的多余空格
for(int i = 0; i < args.length; i++){
// 判断是否为字符串类型
if(args[i].getClass().equals(String.class)){
args[i] = args[i].toString().trim();
}
}
System.out.println("去除空格后参数信息:" + Arrays.toString(args));
// 一定要方改为后的数组args,如果不把args传入的话,运行原始方法使用的还是原来的参数
Object ret = pjp.proceed(args);
return ret;
}
}
- 运行程序
public class App {
public static void main(String[] args) {
ApplicationContext act = new AnnotationConfigApplicationContext(SpringConfig.class);
ResourcesService resourcesService = act.getBean(ResourcesService.class);
boolean flag = resourcesService.openURL("http://pan.baidu.com/haha", " root ");
System.out.println(flag);
}
}