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----------


相关文章
|
2月前
|
人工智能 监控 安全
spring cloud智慧工地信息平台管理系统源码
智慧工地解决方案依托计算机技术、物联网、云计算、大数据、人工智能、VR&AR等技术相结合,为工程项目管理提供先进技术手段,构建工地现场智能监控和控制体系,弥补传统方法在监管中的缺陷,最终实现项目对人、机、料、法、环的全方位实时监控。智慧工地平台支持项目级、公司级、集团级多级权限划分,可根据企业的组织架构进行项目权限、功能权限、数据权限设定。
37 1
|
2月前
|
XML Java 数据库连接
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
Spring Boot的数据访问之Spring Data JPA以及Hibernate的实战(超详细 附源码)
63 0
|
2月前
|
缓存 Java Sentinel
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
Springboot 中使用 Redisson+AOP+自定义注解 实现访问限流与黑名单拦截
|
2月前
|
小程序 JavaScript Java
高校宿舍信息|基于Spring Boot的高校宿舍信息管理系统的设计与实现(源码+数据库+文档)
高校宿舍信息|基于Spring Boot的高校宿舍信息管理系统的设计与实现(源码+数据库+文档)
34 0
|
26天前
|
设计模式 Java 关系型数据库
Spring的配置文件,如何配置端口号,,properties,yml获取配置项等方法,外观模式及其优缺点,日志代表的信息
Spring的配置文件,如何配置端口号,,properties,yml获取配置项等方法,外观模式及其优缺点,日志代表的信息
|
2月前
|
安全 Java 数据库
后端进阶之路——浅谈Spring Security用户、角色、权限和访问规则(三)
后端进阶之路——浅谈Spring Security用户、角色、权限和访问规则(三)
|
21天前
|
SQL Java 数据库
Java一分钟之-Spring Data JPA:简化数据库访问
【6月更文挑战第10天】Spring Data JPA是Spring Data项目的一部分,简化了Java数据库访问。它基于JPA,提供Repository接口,使开发者能通过方法命名约定自动执行SQL,减少代码量。快速上手包括添加相关依赖,配置数据库连接,并定义实体与Repository接口。常见问题涉及主键生成策略、查询方法命名和事务管理。示例展示了分页查询的使用。掌握Spring Data JPA能提升开发效率和代码质量。
36 0
|
2月前
|
Java Spring
spring boot访问接口报500
spring boot访问接口报500
25 2
|
2月前
|
设计模式 Java 数据库连接
【Spring源码】JDBC数据源访问实现
我们再来看看阅读线索三,这方面我们从设计模式进行入手。阅读线索三:从这个模块可以学到什么我们看下以下代码,PreparedStatement实例的是由PreparedStatementCreator实现的。再来看看PreparedStatementCreator接口,一共有三个子类实现。也就是说PreparedStatement的三种不同实现被封装到三个子类中,而具体需要哪种实现,只需要传入不同。
45 1
【Spring源码】JDBC数据源访问实现
|
2月前
|
存储 关系型数据库 MySQL
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)
【mybatis-plus】Springboot+AOP+自定义注解实现多数据源操作(数据源信息存在数据库)