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