使用AspectJ实现AOP的两种方式

一、基于XML的声明式AspectJ
基于XML声明式AspectJ是指通过XML文件来定义切面、切入点及通知,所有的切面切入点通知都必须是定义在aop:config元素内。
1.配置切面
在Spring的哦欸之文件中,配置切面使用的是aop:aspect元素,该元素会将一个定义好事务Spring Bean转换成切面Bean,所以要在配置文件中先定义一个普通的Spring Bean。aop:aspect元素的属性及其描述如下表:

属性名称 描述
id 用于定义该切面的唯一标识
ref 用于引用普通的Spring Bean

2.配置切入点
切入点是通过aop:pointcut元素来定义的。当aop:pointcut元素作为aop:config元素的子元素定义时,标识切入点是全局切入点。它可以被多个切面所共享;当aop:pointcut元素作为aop:aspect元素的子元素定义时,表示该切入点值对当前切面有效。aop:pointcut元素的属性及其描述如下:

属性名称 描述
id 用于指定切入点的唯一标识
ref 用于指定切入点关联的切入点表达式

3.配置通知
分别使用aop:aspect的子元素配置5中常用通知,这5个子元素不支持子元素,使用时可以指定一些属性。

属性名称 描述
pointcut 该属性用于指定一个切入点,Spring将在匹配该表达式的连接点时织入该通知
pointcut-ref 该属性用于指定一个已经存在的切入点名称,如配置该代码中myPointCut。通常pointcut和pointcut-ref两个属性只需要使用其中之一
method 该属性指定一个方法名,指定将切面Bean中的该方法转换为增强
throwing 该属性只对 元素有效,它用与指定一个形象名,异常通知方法可以通过该形参访问目标方法所抛出的异常
returning 该属性只对元素有效,它用于指定一个形参名,后置通知方法可以该形参访问目标方法的返回值

MyAspect_1.java

package com.itheima.aspect.xml;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

/**
* @ClassName: MyAspect 
* @Description: 切面类,在此类中编写通知
 */
public class MyAspect {
	
	/**
	* @Title: myBerore 
	* @Description: 前置通知
	* @Parameters: @param joinpoint
	* @Return void
	* @Throws
	 */
	public void myBerore(JoinPoint joinpoint) {
		System.out.println("前置通知:模拟执行权限检查 ...,");
		System.out.println("目标类是:" +joinpoint.getTarget());
		System.out.println(",被植入增强处理的目标方法为:"+joinpoint.getSignature().getName());
	}
	
	/**
	* @Title: myAfterreturning 
	* @Description: 后置通知
	* @Parameters: @param joinPoint
	* @Return void
	* @Throws
	 */
	public void myAfterreturning(JoinPoint joinPoint) {
		System.out.println("后置通知:模拟记入日志 . . . ,  ");
		System.out.println("被植入增强处理的目标方法为: " +joinPoint.getSignature().getName());
	}
	
	public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		// 开始
		System.out.println("环绕开始:执行目标方法之前,模拟开启事务 . . .");
		//执行当前目标方法
		Object object = proceedingJoinPoint.proceed();
		//结束
		System.out.println("环绕结束: 执行目标方法之后,模拟关闭事务 . . .");
		return object;
	}
	
	/**
	* @Title: myAfterThrowing 
	* @Description: 异常通知
	* @Parameters: @param joinPoint
	* @Parameters: @param throwable
	* @Return void
	* @Throws
	 */
	public void myAfterThrowing(JoinPoint joinPoint, Throwable throwable) {
		System.out.println("异常通知: " + "出错了" + throwable.getMessage());
	}
	
	/**
	* @Title: myAfter 
	* @Description: 最终通知
	* @Parameters: 
	* @Return void
	* @Throws
	 */
	public void myAfter() {
		System.out.println("最终通知: 模拟方法结束后释放资源 . . .");
	}
}

applicationContext.xml



	
	
	
	
	
	
	
	
	
	  
	  
		
		
		
		
		
		
		
		
		
		
		
		
		
	  
	



定义了切入点表达式,该切入点的意思是匹配 com.itheima.jdk 包中任意类的任意方法执行。其中excution()是表达式主体,第一个 * 表示的是返回类型,使用 “ * ”代表所有的类型。com.itheima.jdk 需要拦截的包名,后面第2个 * 表示类名,使用 * 代表所有类; 第3个*表示的是方法名,使用 * 表示所有方法;后面(…) 表示的是方法的参数,其中的“…” 表示任意参数。

TestXmlAspect.java

package com.itheima.aspect.xml;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.itheima.jdk.UserDao;

public class TestXmlAspectj {
	public static void main(String args[]) {
		String XmlPath="com/itheima/aspect/xml/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(XmlPath);
		/*从Spring容器获得内容*/
		UserDao userDao = (UserDao) applicationContext.getBean("userDao");
		userDao.addUser();
	}
}

二、基于注解的声明式AspectJ
使用注解取代Spring配置文件中为实现aop功能的代理解析,便于实现AOP功能配置臃肿。

注解名称 描述
@Aspect 用于定义一个切面
@PointCut 用于定义切入点表达式。在使用时还需要定义一个包含名字和任意参数的方法签名来表示切入点名称。实际上,这个方法签名就是返回一个void值,且方法体为空的普通方法
@Before 用于定义前置通知,相当于BeforeAdivce。在使用时,通常需要指定一个value属性的值,该属性用于指定一个切入点表达式(可以时已有的切入点,也可以是直接定义的切入点)
@AfterReturning 用于定义后置通知,相当于AfterReturningAdvice。在使用时可以指定pointcut/value和returning属性,其中pointcut/value这两个属性的作用一样,都用于指定切入点表达式。returning属性用于表示Advice方法中可定义与此同名的形参,该形参可用于访问目标方法的返回值
@Around 用于定义环绕通知,相当于MethodInterceptor。在使用时需要指定一个value属性,该属性用于指定该通知被植入的切入点
@AfterThrowing 用于定义异常通知来处理程序未处理的异常,相当于ThrowAdvice。在使用时,可以指定pointcut/value和throwing属性。其中pointcut/value用于指定切入点表达式,而throwing属性用于指定一个形参名来表示Advice 方法中可定义与此同名的形参,该形参可以用于访问目标方法抛出的异常
@After 用于定义最终final通知,不管是否异常,该通知都会执行。使用时需要指定一个value属性,该属性用于指定该通知被植入的切入点
@DeclareParents 用于定义引介通知,相当于IntroductionInterceptor

你可能感兴趣的:(使用AspectJ实现AOP的两种方式)