Spring基于AspectJ注解方式的AOP开发

本文介绍了Spring基于AspectJ注解的AOP开发,包括创建web项目,引入jar包,配置目标类和切面类,以及各种通知类型的使用,如前置、后置、环绕和异常通知。通过注解简化了开发过程,但也带来了维护上的不便。文章还探讨了切入点注解@Pointcut的使用,以提高代码的可维护性。
摘要由CSDN通过智能技术生成

Spring基于AspectJ注解方式的AOP开发

注解开发的好处是   开发迅速 ,但是维护必须在源代码处修改,维护时不方便

创建web项目,引入jar包

引入配置文件

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	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
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans> 

创建目标类(被增强的对象)

这次不实现接口,Spring底层会使用Cglib动态代理产生代理对象

public class OrderDao {

	public void save(){
		System.out.println("保存订单...");
	}
	public void update(){
		System.out.println("修改订单...");
	}
	public void delete(){
		System.out.println("删除订单...");
	}
	public void find(){
		System.out.println("查询订单...");
	}
}

配置目标类

<!-- 配置目标类================ -->
	<bean id="orderDao" class="com.itheima.spring.demo1.OrderDao"/>

创建切面类

注解方式的AOP开发,就是的切面类中设置注解

/**
 * 切面类:注解的切面类
 */
public class MyAspectAnno {

	public void before(){
		System.out.println("前置增强===========");
	}
}

配置切面类

​
<!-- 配置切面类================ -->
	<bean id="myAspect" class="com.itheima.spring.demo1.MyAspectAnno"/>

​

 

使用AOP注解对目标类进行加强

首先 要在 配置文件中  打开  注解的AOP开发

<!-- 在配置文件中开启注解的AOP的开发============ -->
	<aop:aspectj-autoproxy/>

接下来就可以在切面类中使用注解了

对save方法进行前置通知

/**
 * 切面类:注解的切面类
 * 在类上添加@Aspect注解
 */
@Aspect
public class MyAspectAnno {
	
	/**
	 * 对sava方法进行前置通知,在before通知上添加@Befor注解
	 */
	@Before("execution(* com.itheima.spring.demo1.OrderDao.save(..))")
	public void before() {
		System.out.println("前置增强===========");
	}
}

编写测试方法

/**
 * Spring的AOP的注解开发
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class SpringDemo1 {
	@Resource(name="orderDao")
	private OrderDao orderDao;
	
	@Test
	public void demo1(){
		orderDao.save();
		orderDao.update();
		orderDao.delete();
		orderDao.find();
	}
}

测试结果

Spring注解的AOP通知的类型

@Before   前置通知

前置通知可以获取切入点信息(其实所有通知都可以获得)

@AfterReturning  后置通知

获取返回值

在delete中添加后置通知,并获取返回值

/**
	 *后置通知 获取返回值
	 * @param result
	 */
	@AfterReturning(value="execution(* com.itheima.spring.demo1.OrderDao.delete(..))",returning="result")
	public void afterReturning(Object result){
		System.out.println("后置增强==========="+result);
	}

测试结果

@Around  环绕通知

在update方法 上添加环绕通知

/**
	 * 环绕通知
	 */
	@Around(value="execution(* com.itheima.spring.demo1.OrderDao.update(..))")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("环绕前增强==========");
		Object obj  = joinPoint.proceed();
		System.out.println("环绕后增强==========");
		return obj;
	}

测试结果

@AfterThrowing   异常抛出通知

在find方法上添加异常抛出通知

/**
	 * 异常抛出通知
	 */
	@AfterThrowing(value="execution(* com.itheima.spring.demo1.OrderDao.find(..))",throwing="e")
	public void afterThrowing(Throwable e){
		System.out.println("异常抛出增强========="+e.getMessage());
	}

测试结果

@After  最终通知

在find方法上添加最终通知

/**
	 * 最终通知
	 */
	@After(value="execution(* com.itheima.spring.demo1.OrderDao.find(..))")
	public void after(){
		System.out.println("最终增强============");
	}

测试结果

Spring的注解的AOP开发的切入点的注解

上面的形式有个问题:即当我们要更改通知作用的目标方法(切入点时)会很麻烦(每次都要写execution函数及其里面的表达式)

解决办法   将切入点用其他名字代替,需要用到切入点的注解@Pointcut

// 切入点注解:
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.find(..))")
	private void pointcut1(){}
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.save(..))")
	private void pointcut2(){}
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.update(..))")
	private void pointcut3(){}
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.delete(..))")
	private void pointcut4(){}

使用时

/**
 * 切面类:注解的切面类
 * 在类上添加Aspect注解
 */
@Aspect
public class MyAspectAnno {
	//前置通知
	@Before(value="MyAspectAnno.pointcut2()")
	public void before(){
		System.out.println("前置增强===========");
	}
	
	// 后置通知:
	@AfterReturning(value="MyAspectAnno.pointcut4()",returning="result")
	public void afterReturning(Object result){
		System.out.println("后置增强==========="+result);
	}
	
	// 环绕通知:
	@Around(value="MyAspectAnno.pointcut3()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("环绕前增强==========");
		Object obj  = joinPoint.proceed();
		System.out.println("环绕后增强==========");
		return obj;
	}
	
	// 异常抛出通知:
	@AfterThrowing(value="MyAspectAnno.pointcut1()",throwing="e")
	public void afterThrowing(Throwable e){
		System.out.println("异常抛出增强========="+e.getMessage());
	}
	
	// 最终通知
	@After(value="MyAspectAnno.pointcut1()")
	public void after(){
		System.out.println("最终增强============");
	}
	
	// 切入点注解:
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.find(..))")
	private void pointcut1(){}
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.save(..))")
	private void pointcut2(){}
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.update(..))")
	private void pointcut3(){}
	@Pointcut(value="execution(* com.itheima.spring.demo1.OrderDao.delete(..))")
	private void pointcut4(){}
}

使用 类名.方法名()代替

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值