Spring学习-22:Spring的AOP:基于AspectJ的XML配置方式开发

本文详细介绍了如何在Spring框架中使用AspectJ配置前置通知、后置通知、环绕通知、异常通知及最终通知,并通过示例代码展示了每种通知类型的配置过程。

话不多说,和上一讲相同,配置项目环境。

先看前置通知。

1、新建目标类,也就是被增强的类:

package com.js.demo2;

public class ProductDao {
	public void add(){
		System.out.println("add...");
	}
	public void update(){
		System.out.println("update...");
	}
	public void delete(){
		System.out.println("delete...");
	}
	public void find(){
		System.out.println("find...");
	}
}

2、定义切面类:

package com.js.demo2;
/**
 * 切面类
 * @author JiangShuai
 *
 */
public class MyAspectXML {
	public void before(){
		System.out.println("前置通知===");
	}
}

3、配置applicationContext.xml

<?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: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">
<!-- 定义被增强的类 -->
<bean id="productDao" class="com.js.demo2.ProductDao"> </bean>
<!-- 定义切面类 -->
<bean id="myAspect" class="com.js.demo2.MyAspectXML"></bean>
<!-- 定义aop的配置 -->
<aop:config>
	<!-- 定义切点 -->
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.add(...))" id="myPointcut"/>
	<aop:aspect ref="myAspectXML">
		<aop:before method="before" pointcut-ref="myPointcut"/>
	</aop:aspect>
</aop:config>
</beans>
4、编写测试类:

package com.js.demo2;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class TestDemo2 {
	@Autowired
	@Qualifier("productDao")
	private ProductDao productDao;
	@Test
	public void demo(){
		productDao.add();
		productDao.find();
		productDao.update();
		productDao.delete();
	}
}

测试结果:



对于后置通知,经过上一讲,我们已经知道,它可以获取方法的返回值。在使用XML配置方式开发AspectJ的时候,该如何实现呢?

修改目标类:

package com.js.demo2;

public class ProductDao {
	public void add(){
		System.out.println("add...");
	}
	public void update(){
		System.out.println("update...");
	}
	public void delete(){
		System.out.println("delete...");
	}
	public String find(){
		System.out.println("find...");
		return "find Success!";
	}
}
修改切面类:

package com.js.demo2;
/**
 * 切面类
 * @author JiangShuai
 *
 */
public class MyAspectXML {
	public void before(){
		System.out.println("前置通知===");
	}
	public void after(Object returnVal){
		System.out.println("后置通知===返回值:"+returnVal);
	}
}
配置xml:

<?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: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">
<!-- 定义被增强的类 -->
<bean id="productDao" class="com.js.demo2.ProductDao"> </bean>
<!-- 定义切面类 -->
<bean id="myAspectXML" class="com.js.demo2.MyAspectXML"></bean>
<!-- 定义aop的配置 -->
<aop:config>
	<!-- 定义切点 -->
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.add(..))" id="myPointcut"/>
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.find(..))" id="myAfter"/>
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.update(..))" id="myAround"/>
	<aop:aspect ref="myAspectXML">
		<!-- 前置通知 -->
		<aop:before method="before" pointcut-ref="myPointcut"/>
		<!-- 后置通知 -->
		<aop:after-returning method="after" pointcut-ref="myAfter" returning="returnVal"/>
		<!-- 环绕通知 -->
	</aop:aspect>
</aop:config>
</beans>
运行测试类:



成功获取了find方法的返回值。

对于环绕通知
修改切面类:

package com.js.demo2;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 切面类
 * @author JiangShuai
 *
 */
public class MyAspectXML {
	public void before(){
		System.out.println("前置通知===");
	}
	public void after(Object returnVal){
		System.out.println("后置通知===返回值:"+returnVal);
	}
	public Object around(ProceedingJoinPoint point) throws Throwable{
		System.out.println("环绕前通知===");
		Object object = point.proceed();
		System.out.println("环绕后通知===");
		return object;
	}
}
修改配置:

<?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: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">
<!-- 定义被增强的类 -->
<bean id="productDao" class="com.js.demo2.ProductDao"> </bean>
<!-- 定义切面类 -->
<bean id="myAspectXML" class="com.js.demo2.MyAspectXML"></bean>
<!-- 定义aop的配置 -->
<aop:config>
	<!-- 定义切点 -->
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.add(..))" id="myPointcut"/>
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.find(..))" id="myAfter"/>
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.update(..))" id="myAround"/>
	<aop:aspect ref="myAspectXML">
		<!-- 前置通知 -->
		<aop:before method="before" pointcut-ref="myPointcut"/>
		<!-- 后置通知 -->
		<aop:after-returning method="after" pointcut-ref="myAfter" returning="returnVal"/>
		<!-- 环绕通知 -->
		<aop:around method="around" pointcut-ref="myAround"/>
	</aop:aspect>
</aop:config>
</beans>
运行:



对于异常和最终通知

修改切面类:

package com.js.demo2;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 切面类
 * @author JiangShuai
 *
 */
public class MyAspectXML {
	public void before(){
		System.out.println("前置通知===");
	}
	public void after(Object returnVal){
		System.out.println("后置通知===返回值:"+returnVal);
	}
	public Object around(ProceedingJoinPoint point) throws Throwable{
		System.out.println("环绕前通知===");
		Object object = point.proceed();
		System.out.println("环绕后通知===");
		return object;
	}
	public void afterthrowing(Throwable e){
		System.out.println("糟糕,出错了===错误信息:"+e.getMessage());
	}
	public void afterFinal(){
		System.out.println("最终通知===");
	}
}
修改目标类:

package com.js.demo2;

public class ProductDao {
	public void add(){
		System.out.println("add...");
	}
	public void update(){
		System.out.println("update...");
	}
	public void delete(){
		System.out.println("delete...");
	}
	public String find(){
		System.out.println("find...");
		int a = 1/0;
		return "find Success!";
	}
}
修改配置:

?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: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">
<!-- 定义被增强的类 -->
<bean id="productDao" class="com.js.demo2.ProductDao"> </bean>
<!-- 定义切面类 -->
<bean id="myAspectXML" class="com.js.demo2.MyAspectXML"></bean>
<!-- 定义aop的配置 -->
<aop:config>
	<!-- 定义切点 -->
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.add(..))" id="myPointcut"/>
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.find(..))" id="myAfter"/>
	<aop:pointcut expression="execution(* com.js.demo2.ProductDao.update(..))" id="myAround"/>
	<aop:aspect ref="myAspectXML">
		<!-- 异常通知 -->
		<aop:after-throwing method="afterthrowing" pointcut-ref="myAfter" throwing="e"/>
		<!-- 最终通知 -->
		<aop:after method="afterFinal" pointcut-ref="myAfter"/>
	</aop:aspect>
</aop:config>
</beans>
运行结果:



基于注解的AspectJ开发就介绍到这,熟能生巧,多练习配置,思考思考原理即可熟练掌握。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值