Spring AOP Annotation 的“零配置” 的学习方法(一)

Spring AOP 学习

最近公司来新招了几位新同事,对Spring AOP 不是多理解,借此机会整理下Spring AOP 基于Annotation 零配置的方法, 【只是个人学习方法,如有错误请指教】
     下面主要描述spring中使用AOP的两个例子:一个采用注解的方式来实现,另一个采用声 明的方式来实现。描述这两个例子有两个目的:
一是熟悉spring中的AOP使用,二就是以这些 
例子作为以后对spring AOP分析作铺垫。废话少说,首先复兴下AOP种一些比较重要的概念: 
    Joinpoint(连接点):程序执行时的某个特定的点,在Spring中就是某一个方法的执行 
    Pointcut(切点):说的通俗点,spring中AOP的切点就是指一些方法的集合,而这些方法 
是需要被增强、被代理的。一般都是按照一定的约定规则来表示的,如正则表达式等。切点是 
由一类连接点组成。 
    Advice(通知):还是说的通俗点,就是在指定切点上要干些什么。 
    Advisor(通知器):其实就是切点和通知的结合 
    好了,概念就不多说了,如果要了解详细点,可以google一把,现在先描述出两个例子中 的一个,其中一个是采用注解的方式来实行切面编程,具体 如下: 
1.Spring 的配置文件 如

2.编写目标对象类
package com.teamsun.spring.serviceImp;

import org.springframework.stereotype.Component;

import com.teamsun.spring.service.FourAgviceService;

@Component(value="f")
public class FourAgviceServiceImp implements FourAgviceService {

	@Override
	public String sayHello(String name) {
		return "您好:"+name+"Hello Spring Aop";
	}

}
2.编写切面类
package com.teamsun.spring.aop;

import java.util.Arrays;

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

@Aspect
public class FourAdvice {
	// final 织入表达式
	public static final String AUT = "execution(* com.teamsun.spring.serviceImp.FourAgviceServiceImp.*(..))";

	/**
	 * 定义Around增强处 Around 增强处,是一个功能比较强大的增强处理。 
	 * 		1.相当于 Before增强处和AfterReturning增强处的总和,
	 * 		2.定义一个Around增强处理方法,第一个处形参必须是ProceedingJoinPoint类型。
	 * 		3.在增强处理方法内,调用ProceedingJoinPoint 的 proceed方法,才会执行目标方法
	 * 访问目标方法的参数方法
	 * 		1.Object[] getArgs(): 返回执行目标方法时的参数。
	 * 		2.Signature getSignature() :返回被增强方法的相关信息
	 * 		3.Object getTarget():返回被织入增强处的目标方法
	 * 		4.Object getThis():返回AOP框架为目标对象生成的代理对象
	 */
	@Around(AUT)
	public Object processTx(ProceedingJoinPoint jp) throws Throwable {
		System.out.println("Around 增强处:执行目标之前 模拟开启事物");
		// 获取目标方法的参数
		Object[] args = jp.getArgs();
		// 判断第一个参数是否为String类型
		if (args != null && args.length > 0
				&& args[0].getClass() == String.class) {
			// 改变目标方法的第一个参数
			args[0] = "被修改的参数";
		}
		// 执行目标方法,并保存目标返回值
		Object rvt = jp.proceed(args);
		System.out.println("Around 增强处:执行目标方法后 模拟结束事物 ");
		return rvt + "【新增的内容】";
	}

	/**
	 * 定义Before 增强处, 
	 * 		1.使用@Before标注是,通常需要指定一个Value属性值,
	 * 		2.该属性值指定一个切入点表达式,可以是已有的,也可以自己直接定义一个切入点表达式
	 * 
	 */
	@Before(AUT)
	public void Beford(JoinPoint jp) {
		System.out.println("Before 增强处:模拟权限检测");
		System.out.println("Before 增强处:被织入增强方法名称      "
				+ jp.getSignature().getName());
		System.out.println("Before 增强处:被织入增强方法的参数      "
				+ Arrays.toString(jp.getArgs()));
		System.out.println("Before 增强处:被织入增强方法的目标对象      " + jp.getTarget());

	}

	/**
	 * 定义AfterRetruning 增强处
	 *		1. 使用@AfterRetruning来标注一个AfterRetruning增强处理,
	 *   	   AfterRetruning增强处将在目标方法正常完成后被织入 使用@AfterRetruning
	 *		2.Annonation 是 可以指定两个常用参数
	 *		 	@piontcut/value 两个属性作用是一样的,定义一个就OK,都是用来指定该切入点的表达式。
	 *		 	@returning 指定一个返回值形参名,增强处定义方法可以通过该形参名来访问目标方法的返回值
	 */
	@AfterReturning(returning = "rvt", pointcut = AUT)
	public void BeforeReturn(JoinPoint jp, Object rvt) {
		System.out.println("AfterReturning 增强处:回去目标方法返回值" + rvt);
		System.out.println("AfterReturning 增强处:模拟日志记录");
		System.out.println("AfterReturning 增强处:被织入增强方法名称      "
				+ jp.getSignature().getName());
		System.out.println("AfterReturning 增强处:被织入增强方法的参数      "
				+ Arrays.toString(jp.getArgs()));
		System.out.println("AfterReturning 增强处:被织入增强方法的目标对象      "
				+ jp.getTarget());
	}

	/**
	 * 定义After 增强处 
	 * 		1.它和AfterRetruning增强处类似, AfterRetruning 是在目标方法正常结束后被织入,
	 *	    2.After增强处理 不管不管目标方法如何结束,它都会织入
	 */

	@After(AUT)
	public void After(JoinPoint jp) {
		System.out.println("After 增强处:模拟方法结束后,释放资源");
		System.out.println("After 增强处:被织入增强方法名称      "
				+ jp.getSignature().getName());
		System.out.println("After 增强处:被织入增强方法的参数      "
				+ Arrays.toString(jp.getArgs()));
		System.out.println("After 增强处:被织入增强方法的目标对象      " + jp.getTarget());

	}

}
3.编写测试类
package com.teamsun.spring.serviceImp;

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

import com.teamsun.spring.service.FourAgviceService;

public class FourAgviceServiceImpTest {
	@Test
	public void tsetSayHello() {
		ApplicationContext cx = new ClassPathXmlApplicationContext(
				"com/teamsun/spring/cfg/applicationContxt.xml");
		FourAgviceService f = (FourAgviceService) cx.getBean("f");
		String name = f.sayHello("张三");
		System.out.println(name);
		
	}

}
4.测试结果


5.本次项目所有的jar

OK,今天就到这了,多多指教。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值