Spring:AOP面向切面的编程方式

    在Spring中面向切面编程有两种方式,分别是通过注解的方式和通过xml的方式,以下案例是在Spring3.x版本进行讲解。

一、execution函数

1.1、语法

    execution(<访问修饰符>?<方法的返回值类型><方法名>(<参数列表>)<异常>)

1.2、规则

规则表达式示例
匹配所有类的public方法execution(public **(..)) 
匹配指定包下所有类的方法(不包含子包)execution(* 包名.*(..))execution(* test.aop.t1.*(..))
匹配指定包下所有类的方法(包含子包)execution(* 包名.**(..))execution(* test.aop.t1..*(..))
匹配指定类下的所有方法execution(* 包名.类名.*(..))execution(* test.aop.t1.UserDao.*(..))
匹配指定类下的指定方法execution(* 包名.类名.方法名(..))execution(* test.aop.t1.UserDao.add(..))
匹配实现指定接口的所有类的方法execution(* 包名.接口名+*(..))execution(* test.aop.t1.UserDao+*(..))
匹配所有名称以save开头的方法execution(* save*(..)) 
二、使用注解的方式实现AOP

2.1、导入Spring的类库


2.2、创建业务功能类UserDao

package test.aop.t1;

public class UserDao {

	public void add() {
		System.out.println("添加用户");
	}
	
	public int update() {
		System.out.println("修改用户");
		return 1;
	}
	
	public void find() {
		System.out.println("查询用户");
//		System.out.println(10/0); //制造异常
	}
}

2.3、创建切面类

package test.aop.t1;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

/**
 * 切面类:就是切点与增强的结合
 * 
 * @author thinkpad
 *
 */
@Aspect
public class MyAspect {

	/**
	 * 前置通知
	 */
	@Before(value = "execution(* test.aop.t1.UserDao.add(..))")
	public void before() {
		System.out.println("前置增强...");
	}
	
	/**
	 * 后置通知,可以获得方法的返回值
	 */
	@AfterReturning(returning = "returnVal", value = "execution(* test.aop.t1.UserDao.update(..))")
	public  void afterReturning(Object returnVal){
		System.out.println("后置增强...方法的返回值" + returnVal);
	}
	
	/**
	 * 环绕通知,可以阻止目标方法执行
	 * @return 
	 * @throws Throwable 
	 */
	@Around(value = "MyAspect.myPointcut()")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("环绕前增强...");
		Object obj = joinPoint.proceed(); //代表目标方法执行
		System.out.println("环绕后增强...");
		return obj;
	}
	
	/**
	 * 抛出异常通知
	 */
	@AfterThrowing(throwing="e", value = "MyAspect.myPointcut()")
	public void afterThrowing(Throwable e){
		System.out.println("不好了,出异常了....,异常信息:"+e.getMessage());
	}
	
	/**
	 * 最终通知,不管是否异常,该通知都会执行
	 */
	@After(value = "MyAspect.myPointcut()")
	public void after(){
		System.out.println("总会执行");
	}
	
	/**
	 * 定义切点,目的是定义通用的execution表达式
	 */
	@Pointcut(value = "execution(* test.aop.t1.UserDao.find(..))")
	private void myPointcut() {
		
	}
}

2.4、配置切面

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

	<!-- 自动生成代理 -->
	<aop:aspectj-autoproxy/>
	
	<bean id="myAspect" class="test.aop.t1.MyAspect"/>

	<bean id="userDao" class="test.aop.t1.UserDao"/>
	
</beans>

2.5、测试

package test.aop.t1;

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

public class JTest {

	@Test
	public void test() {
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao dao = (UserDao) cxt.getBean("userDao");
//		dao.add();
//		dao.update();
		dao.find();
	}
}

2.6、运行结果


三、使用XML的方式实现AOP

3.1、Spring类库


3.2、创建业务功能类UserDao

package test.aop;

public class UserDao {

	public void add() {
		System.out.println("添加用户");
	}
	
	public int update() {
		System.out.println("修改用户");
		return 1;
	}
	
	public void find() {
		System.out.println("查询用户");
//		System.out.println(10/0); //制造异常
	}
}

3.3、创建切面类

package test.aop;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * 切面类:就是切点与增强的结合
 * 
 * @author thinkpad
 *
 */
public class MyAspect {

	/**
	 * 前置通知
	 */
	public void before() {
		System.out.println("前置增强...");
	}
	
	/**
	 * 后置通知,可以获得方法的返回值
	 */
	public  void afterReturning(Object returnVal){
		System.out.println("后置增强...方法的返回值" + returnVal);
	}
	
	/**
	 * 环绕通知,可以阻止目标方法执行
	 * @return 
	 * @throws Throwable 
	 */
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("环绕前增强...");
		Object obj = joinPoint.proceed(); //代表目标方法执行
		System.out.println("环绕后增强...");
		return obj;
	}
	
	/**
	 * 抛出异常通知
	 */
	public void afterThrowing(Throwable e){
		System.out.println("不好了,出异常了....,异常信息:"+e.getMessage());
	}
	
	/**
	 * 最终通知,不管是否异常,该通知都会执行
	 */
	public void after(){
		System.out.println("总会执行");
	}
	
}

3.4、在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="userDao" class="test.aop.UserDao"/>

	<bean id="myAspect" class="test.aop.MyAspect"/>
	
	<aop:config>
		<!-- 定义切点 -->
		<aop:pointcut expression="execution(* test.aop.UserDao.add(..))" id="addPointcut"/>
		<aop:pointcut expression="execution(* test.aop.UserDao.update(..))" id="updatePointcut"/>
		<aop:pointcut expression="execution(* test.aop.UserDao.find(..))" id="findPointcut"/>
		<!-- 定义切面 -->
		<aop:aspect ref="myAspect">
			<aop:before method="before" pointcut-ref="addPointcut"/>
			<aop:after-returning method="afterReturning" returning="returnVal" pointcut-ref="updatePointcut"/>
			<aop:around method="around" pointcut-ref="findPointcut"/>
			<aop:after-throwing method="afterThrowing" throwing="e" pointcut-ref="findPointcut"/>
			<aop:after method="after" pointcut-ref="findPointcut"/>
		</aop:aspect>
	</aop:config>
	
</beans>

3.5、测试

package test.aop;

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

public class JTest {

	@Test
	public void test() {
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		UserDao dao = (UserDao) cxt.getBean("userDao");
//		dao.add();
//		dao.update();
		dao.find();
	}
}

3.6、运行结果


四、源代码

Spring通过注解实现AOP

Spring通过XML实现AOP


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值