Spring-AOP @AspectJ进阶之访问连接点信息

简介: Spring-AOP @AspectJ进阶之访问连接点信息

概述


AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象,如果是环绕增强时,使用org.aspectj.lang.ProceedingJoinPoint表示连接点对象,该类是JoinPoint的子接口。


任何一个增强方法都可以通过将第一个入参声明为JoinPoint访问到连接点上下文的信息。


我们先来了解一下这两个接口的主要方法:


JoinPoint


java.lang.Object[] getArgs():获取连接点方法运行时的入参列表;


Signature getSignature() :获取连接点的方法签名对象;


java.lang.Object getTarget() :获取连接点所在的目标对象;


java.lang.Object getThis() :获取代理对象本身;


ProceedingJoinPoint


ProceedingJoinPoint继承JoinPoint子接口,它新增了两个用于执行连接点方法的方法:


  • java.lang.Object proceed() :通过反射执行目标对象的连接点处的方法;
  • java.lang.Object proceed(java.lang.Object[] args) :通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。


实例


代码已托管到Github—> https://github.com/yangshangwei/SpringMaster

aHR0cDovL2ltZy5ibG9nLmNzZG4ubmV0LzIwMTcwOTEyMTMyNzU3OTQx.png

业务类

package com.xgj.aop.spring.advisor.aspectJAdvance.joinPoint;
import org.springframework.stereotype.Component;
/**
 * 
 * 
 * @ClassName: LogicService
 * 
 * @Description: @Component标注的Bean
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月12日 上午1:09:38
 */
@Component
public class LogicService {
  public void dealLogic(String bussiness) {
    System.out.println("deal Logic:" + bussiness);
  }
}

编写切面

package com.xgj.aop.spring.advisor.aspectJAdvance.joinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
 * 
 * 
 * @ClassName: JoinPointAspect
 * 
 * @Description: @Aspect标注的切面
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年9月12日 上午1:10:40
 */
@Aspect
public class JoinPointAspect {
  // ①环绕增强
  @Around("execution(* dealLogic(..)) && target(com.xgj.aop.spring.advisor.aspectJAdvance.joinPoint.LogicService)")
  public void crossCodeCutting(ProceedingJoinPoint pjp) throws Throwable { // ②声明连接点入参
    System.out.println("-------ProceedingJoinPoint begin----------");
    // ③访问连接点信息
    System.out.println("arg[0]:" + pjp.getArgs()[0]);
    System.out.println("signature:" + pjp.getTarget().getClass());
    // ④通过连接点执行目标对象的方法
    pjp.proceed();
    System.out.println("-------ProceedingJoinPoint end----------");
  }
}


在①处,我们声明了一个环绕增强,在②处增强方法的第一个入参声明为PreceedingJoinPoint类型(注意一定要在第一个位置),在③处,我们通过连接点对象pjp访问连接点的信息。在④处,我们通过连接点调用目标对象的方法

将业务Bean和切面配置到配置文件中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:aop="http://www.springframework.org/schema/aop"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:context="http://www.springframework.org/schema/context"
  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
    http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">
<!-- (1)声明Context命名空间以及Schema文件   (2)扫描类包以及应用注解定义的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJAdvance.joinPoint"/>
<!-- 基于@AspectJ切面的驱动器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 使用了@AspectJ注解的切面类 -->
<bean class="com.xgj.aop.spring.advisor.aspectJAdvance.joinPoint.JoinPointAspect"/>
</beans>


测试类

package com.xgj.aop.spring.advisor.aspectJAdvance.joinPoint;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class JoinPointAspectTest {
  @Test
  public void test() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext(
        "classpath:com/xgj/aop/spring/advisor/aspectJAdvance/joinPoint/conf-joinPoint.xml");
    LogicService logicService = ctx.getBean("logicService",
        LogicService.class);
    logicService.dealLogic("PROGRAMMING");
  }
}


运行结果

2017-09-12 01:19:27,120  INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@292898f5: startup date [Tue Sep 12 01:19:27 BOT 2017]; root of context hierarchy
2017-09-12 01:19:27,196  INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJAdvance/joinPoint/conf-joinPoint.xml]
-------ProceedingJoinPoint begin----------
arg[0]:PROGRAMMING
signature:class com.xgj.aop.spring.advisor.aspectJAdvance.joinPoint.LogicService
deal Logic:PROGRAMMING
-------ProceedingJoinPoint end----------


相关文章
|
6月前
|
缓存 Java Sentinel
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
|
30天前
|
开发框架 前端开发 网络协议
Spring Boot结合Netty和WebSocket,实现后台向前端实时推送信息
【10月更文挑战第18天】 在现代互联网应用中,实时通信变得越来越重要。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为客户端和服务器之间的实时数据传输提供了一种高效的解决方案。Netty作为一个高性能、事件驱动的NIO框架,它基于Java NIO实现了异步和事件驱动的网络应用程序。Spring Boot是一个基于Spring框架的微服务开发框架,它提供了许多开箱即用的功能和简化配置的机制。本文将详细介绍如何使用Spring Boot集成Netty和WebSocket,实现后台向前端推送信息的功能。
310 1
|
3月前
|
缓存 NoSQL Java
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
【Azure Redis 缓存】示例使用 redisson-spring-boot-starter 连接/使用 Azure Redis 服务
|
1月前
|
设计模式 前端开发 Java
Spring MVC——项目创建和建立请求连接
MVC是一种软件架构设计模式,将应用分为模型、视图和控制器三部分。Spring MVC是基于MVC模式的Web框架,通过`@RequestMapping`等注解实现URL路由映射,支持GET和POST请求,并可传递参数。创建Spring MVC项目与Spring Boot类似,使用`@RestController`注解标记控制器类。
37 1
Spring MVC——项目创建和建立请求连接
|
4月前
|
缓存 监控 Java
优化Spring Boot应用的数据库访问性能
优化Spring Boot应用的数据库访问性能
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
57 2
|
6月前
|
小程序 JavaScript Java
高校宿舍信息|基于Spring Boot的高校宿舍信息管理系统的设计与实现(源码+数据库+文档)
高校宿舍信息|基于Spring Boot的高校宿舍信息管理系统的设计与实现(源码+数据库+文档)
77 0
|
4月前
|
Java Spring
spring boot 中默认最大线程连接数,线程池数配置查看
spring boot 中默认最大线程连接数,线程池数配置查看
350 4
|
3月前
|
Java Spring
【Azure Service Bus】使用Spring Cloud integration示例代码,为多个 Service Bus的连接使用 ConnectionString 方式
【Azure Service Bus】使用Spring Cloud integration示例代码,为多个 Service Bus的连接使用 ConnectionString 方式
|
3月前
|
Java Spring
Spring Boot实战:静态资源无法访问
Spring Boot实战:静态资源无法访问
72 0
下一篇
无影云桌面