AspectJ

本文介绍了基于Java的AOP框架AspectJ,包括Spring对其切点表达式的支持、@AspectJ新增功能。阐述了AspectJ通知类型,详细说明了开发步骤,如导包、创建配置文件、编写切面类等,还介绍了注解方式实现的相关内容,如替换bean、声名切面等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、简介

  1. AspectJ是一个基于Java语言的AOP框架
  2. Spring2.0以后新增了对AspectJ切点表达式支持
  3. @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面

二、AspectJ通知类型

三、开发步骤

1、导包

先引入Spring框架开发的基本开发包

再引入Spring框架的AOP的开发包

spring的传统AOP的开发的包

spring-aop-4.2.4.RELEASE.jar

com.springsource.org.aopalliance-1.0.0.jar

aspectJ的开发包

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

spring-aspects-4.2.4.RELEASE.jar

2、创建spring的配置文件,引入aop的约束

<beans xmlns="http://www.springframework.org/schema/beans"
		       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		       xmlns:aop="http://www.springframework.org/schema/aop"
		       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">

3、编写切面类

/**
 * 
 *AspectJ的通知
 *
 */
public class MyAdvice {

	/**
	 * 后置通知
	 * @param joinPoint
	 */
	public   void  before(JoinPoint  joinPoint){
		System.out.println("前置通知:"+joinPoint.getSignature().getName());	
	}
	/**
	 * 后置通知  可以获取到方法的返回值
	 * res形参名需要在配置文件中进行配置 ;	<aop:after-returning method="after" returning="res"/>
	 */
	public  void  after(JoinPoint  joinPoint,Object res){
		System.out.println("后置通知:"+res);
	}
	/**
	 * 异常通知
	 * e参数名需要配置:  <aop:after-throwing method="afterthrowing" pointcut-ref="mycut" throwing="e"/>
	 * @param joinPoint
	 */
	public   void  afterthrowing(JoinPoint  joinPoint,Exception e){
		System.out.println("异常通知:"+e.getMessage());	
	}
	
	/**
	 * 最终通知
	 * @param joinPoint
	 */
	public   void  afterFinal(JoinPoint  joinPoint){
		System.out.println("最终通知");	
	}
	/**
	 * 环绕通知
	 */
	@SuppressWarnings("finally")
	public   Object  around(ProceedingJoinPoint   joinPoint){
	
		Object proceed =null;
		try {
			//前置通知
			System.out.println("前置通知-------");
			//执行目标方法
			proceed= joinPoint.proceed();
			System.out.println("后置通知-------");			
		//后置通知	
			
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			//异常通知
			System.out.println("异常通知-------");
		}
		finally {
			System.out.println("最终通知-------");
			//最终通知
			return  proceed;
		}
	}

}

 目标类:

public class UserServiceImpl implements UserService{

	@Override
	public void add() {
		System.out.println("add");
	}

	@Override
	public void delete() {
		System.out.println("delete");
	}

	@Override
	public void update() {
		System.out.println("update");
	}

	@Override
	public void query() {
		System.out.println("query");
	}

spring中的配置:

<!-- Spring的aop编程
     	1.引入aop相关的jar  4个
     	引入命名空间和约束
      -->
      
      <!-- 1.配置目标类 -->
   <bean id="userService" class="spring_aspectj_4.UserServiceImpl"></bean>
   <!-- 2.配置通知类 -->
	<bean id="advice" class="spring_aspectj_4.MyAdvice"></bean>
	
	<aop:config proxy-target-class="false">
	<!-- 配置一个公共的切点 -->
	<aop:pointcut expression="execution(* spring_aspectj_4.*.*(..))" id="mycut"/>
	
	<aop:aspect ref="advice">
		<aop:before method="before" pointcut-ref="mycut"/>
		<aop:after-returning method="after" returning="res" pointcut-ref="mycut"/>
		
		<aop:after-throwing method="afterthrowing" pointcut-ref="mycut" throwing="e"/>
		 
		<aop:after method="afterFinal" pointcut-ref="mycut" />
		
		<aop:around method="around" pointcut-ref="mycut"/>
	</aop:aspect>
	
	</aop:config>

四、注解方式实现

 

1、替换bean

 <!-- 1.配置目标类 -->
    <bean id="userService" class="spring_aspectj_4.UserServiceImpl"></bean>
<!-- 2.配置通知类 -->
    <bean id="advice" class="spring_aspectj_4.MyAdvice"></bean>

 

 

2、@Aspect声名了切面,代替<aop:aspect ref="advice">

3、替换公共切入点(简化引入切点)

前:

<!-- 配置一个公共的切点 -->
<aop:pointcut expression="execution(* spring_aspectj_4.*.*(..))" id="mycut"/>

后: 

@Pointcut("execution(* spring_aspectj_anno_01.UserServiceImpl.*(..))")
	public void myCut() {
		
	}

 完整切点类:
 

@Component
@Aspect
public class MyAdvice {
	
	@Pointcut("execution(* spring_aspectj_anno_01.UserServiceImpl.*(..))")
	public void myCut() {	
	}
	/**
	 * 后置通知
	 * @param joinPoint
	 */
	@Before("myCut()")
	public   void  before(JoinPoint  joinPoint){
		System.out.println("前置通知:"+joinPoint.getSignature().getName());	
	}
	/**
	 * 后置通知  可以获取到方法的返回值
	 * res形参名需要在配置文件中进行配置 ;	<aop:after-returning method="after" returning="res"/>
	 */
	@AfterReturning(value="myCut()",returning="res")
	public  void  after(JoinPoint  joinPoint,Object res){
		System.out.println("后置通知:"+res);
	}
	/**
	 * 异常通知
	 * e参数名需要配置:  <aop:after-throwing method="afterthrowing" pointcut-ref="mycut" throwing="e"/>
	 * @param joinPoint
	 */
	@AfterThrowing(value="myCut()",throwing="e")
	public   void  afterthrowing(JoinPoint  joinPoint,Exception e){
		System.out.println("异常通知:"+e.getMessage());	
	}
	
	/**
	 * 最终通知
	 * @param joinPoint
	 */
	@After("myCut()")
	public   void  afterFinal(JoinPoint  joinPoint){
		System.out.println("最终通知");	
	}
	/**
	 * 环绕通知
	 */
	@Around("execution(* spring_aspectj_anno_01.UserServiceImpl.*(..))")
	@SuppressWarnings("finally")
	public   Object  around(ProceedingJoinPoint   joinPoint){
		Object proceed =null;
		try {
			//前置通知
			System.out.println("前置通知-------");
			//执行目标方法
			proceed= joinPoint.proceed();
			System.out.println("后置通知-------");			
		//后置通知				
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			
			//异常通知
			System.out.println("异常通知-------");
		}
		finally {
			System.out.println("最终通知-------");
			//最终通知
			return  proceed;
		}
	}

}

spring配置文件:

配置头: 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
     xmlns:aop="http://www.springframework.org/schema/aop"
    
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd">

  2、开启组件扫描

<context:component-scan base-package="spring_aspectj_anno_01"></context:component-scan>

3、开启AOP注解 

<!-- 开启AOP注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

 

04-01
<think>好的,用户想了解AspectJ的使用教程或官方文档。首先,我需要整理现有的引用信息,看看有哪些可用的资源。根据引用内容,用户可能对在Android或Spring中使用AspectJ感兴趣,或者如何引入依赖。 首先,引用[1]提到在Android中直接引入AspectJ的方式,引用[2]和[3]讨论了Spring AOP与AspectJ的结合,引用[4]给出了添加依赖的示例。用户可能需要基础教程和官方文档的指引。 我应该分步骤回答,先介绍AspectJ的基本概念,再讲解使用方式,括依赖配置、切面编写和编译配置。然后提供官方文档链接和相关教程资源。同时,根据引用内容,需要区分在Spring和Android中的不同使用方法,避免混淆。 需要确保回答结构清晰,符合用户要求的系统级指令,比如正确使用LaTeX格式,不过这里可能用不上数学公式。但要注意中文回答,生成相关问题,并正确添加引用标识。最后,生成的相关问题应该围绕AspectJ的应用场景、依赖注入、与Spring AOP的区别等,帮助用户深入理解。</think>### AspectJ 使用教程及官方文档指引 #### 一、AspectJ 简介 AspectJ 是一个面向切面编程(AOP)的扩展工具,通过增强 Java 语法(如注解、切入点表达式等)实现代码的横向关注点分离。它支持编译时编织(CTW)和加载时编织(LTW),适用于日志、事务、权限控制等场景[^2][^3]。 --- #### 二、AspectJ 使用步骤 ##### 1. 添加依赖 在 Maven 项目中引入 AspectJ 核心依赖: ```xml <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.6</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.5</version> </dependency> ``` 引用自依赖配置示例[^4]。 ##### 2. 编写切面类 使用 `@Aspect` 注解定义切面,结合 `@Pointcut` 和 `@Around` 等注解实现逻辑: ```java @Aspect public class LoggingAspect { @Pointcut("execution(* com.example.service.*.*(..))") public void serviceMethods() {} @Around("serviceMethods()") public Object logMethod(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("方法执行前: " + joinPoint.getSignature()); Object result = joinPoint.proceed(); System.out.println("方法执行后"); return result; } } ``` ##### 3. 配置编织方式 - **编译时编织**:通过 AspectJ 编译器(`ajc`)在编译阶段织入切面。 - **加载时编织**:在 JVM 启动时添加参数 `-javaagent:aspectjweaver.jar` 实现动态织入。 --- #### 三、AspectJ 在 Spring 与 Android 中的使用 1. **Spring 集成** Spring AOP 默认使用动态代理,而 AspectJ 提供更强大的功能(如非 Spring 管理对象的注入)。需在配置中启用 `@EnableAspectJAutoProxy`。 2. **Android 应用** 通过 Gradle 插件(如 `aspectj-tools`)配置编译时编织,直接引入 AspectJ 依赖并定义切面逻辑[^1]。 --- #### 四、官方文档与资源 1. **AspectJ 官方文档** 访问 [AspectJ 官网](https://www.eclipse.org/aspectj/) 获取完整语法和示例。 2. **教程推荐** - [AspectJ 编程指南](https://www.eclipse.org/aspectj/doc/released/progguide/index.html) - [Spring 与 AspectJ 整合文档](https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-using-aspectj) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值