您的位置:首页 > 编程语言 > Java开发

SpringAOP技术学习---Day3

2017-08-22 15:26 465 查看
本篇博客知识点

学习SpringAOP第三种技术—利用注解完成拦截

AOP技术的本质为一个公式

切面 = 切点 + 通知


四种技术都只是通过不同形式完成这个公式而言,第三种是通过注解

第一步:写一个类 就是我们的切面

类名任意但是类前面必须加一个注解 @Aspect



底层Spring可以通过这个注解知道这个类就是我们的切面。

第二步:写切点 :字符内容为 切点语言 AspectJ

切点有两种形式写法,第一种是通过类成员变量



第二种形式:写在一个成员方法上,



第三步:写通知,通知有多种

通过注解写到成员方法名字上,方法内的 就是切面执行函数。

两种对应前面两个切点的使用方法





下面是对几种常用的拦截方法介绍

@Before :原型对象执行前拦截,

@After:原型对象执行后拦截

@Around: 可以原型对象执行前后拦截

@AfterReturning:原型对象执行时正常返回结果未出错时候 触发

@AfterThrowing:原型对象执行时未正常返回结果出错时候 触发

下面是两个切面的代码

package cn.hncu2.v3;

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.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;

//切面= 切点  + 通知
//@Aspect = @Pointcut + (@Before | @After | Around | @AfterReturning | @AfterThrowing 等当中至少有1种)

@Aspect
public class MyAdvisor {

@Pointcut(value="execution( * cn..Cat.*(..) )")  //@Pointcut中的value属性来指定切点的表达式----用aspectj切点语言
public void aa(){ //该方法没别的功能,就是为了让@Pointcut有个寄居的地方,同时也用于标识该注解
}

@Pointcut(value="execution( * cn..Person.*(..) ) ")
public void bb(){
}

@Before(value="aa()")  //由@Before通知的value属性指定PointCut(本例为aa()方法上的切点)
public void bf(){
System.out.println("前面拦拦......");
}

@After(value="aa()")
public void after1(){
System.out.println("后面拦拦1.....");
}

//下面的方法可以采用空参,但通过手动注入一个JoinPoint类型的参数,可以获得拦截"连接点"的信息如: 是否为方法执行、被拦截方法的名字、方法的对象等
@After(value="bb()")
public void after2(JoinPoint jp){//通过手动注入 jp参数 ---缺点:依赖JoinPoint类,因此如果没必要的话,就不加这个参数
System.out.println("后面拦拦2.....:"+ jp.getKind()+","+jp.getSignature().getName()+","+jp.getTarget() );
}

@Around(value="aa()") //Around通知的拦截方法必须依赖一个ProceedingJoinPoint参数,否则无法放行, 同时方法要返回Object(被放行方法的返回值)
public Object around(ProceedingJoinPoint p) throws Throwable{  //ProceedingJoinPoint 是 JoinPoint 的子类
System.out.println("前前前拦拦.....:"+ p.getKind()+","+p.getSignature().getName()+","+p.getTarget() );
Object res = p.proceed(); //放行
System.out.println("后后后拦拦....");
return res;
}

@AfterReturning(value="aa()")
public void afterReturn(){ //该方法可以注入JoinPoint参数,也可以不注入
System.out.println("方法正常返回之后......");
}
@AfterThrowing(value="aa()")
public void afterThrow(){ //该方法可以注入JoinPoint参数,也可以不注入
System.out.println("方法抛出异常之后.....");
}

}


package cn.hncu2.v3;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

//切面= 切点  + 通知
//@Aspect = @Pointcut + (@Before | @After | Around | @AfterReturning | @AfterThrowing 等当中至少有1种)

@A
4000
spect
public class MyAdvisor2 {

//用表达式字符串来代替切点
private final String CUT="execution( * cn..Person.*(..) )";

@Before(CUT)
public void bf(){
System.out.println("前面拦拦......");
}

@Around(CUT)
public Object around(ProceedingJoinPoint p) throws Throwable{  //ProceedingJoinPoint 是 JoinPoint 的子类
System.out.println("前前前2拦拦.....:"+ p.getKind()+","+p.getSignature().getName()+","+p.getTarget() );
Object res = p.proceed(); //放行
System.out.println("后后后2拦拦....");
return res;
}

}


vvv.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:context="http://www.springframework.org/schema/context"
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/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
">

<!-- 自动代理  , 低版Spring可以用该自动代理类  替代 下面的自动代理标签
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>
-->

<!-- 自动代理的标签 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

<!-- 基于注解的切面 -->
<!-- <bean class="cn.hncu.v3.MyAdvisor"></bean> -->
<bean class="cn.hncu.v3.MyAdvisor2"></bean>

<bean id="p" class="cn.hncu.v3.Person"></bean>
<bean id="cat" class="cn.hncu.v3.Cat"></bean>

</beans>


package cn.hncu.v3;

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

public class Client {
@Test
public void t1(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("cn/hncu/v3/vvv.xml");

Person p = ctx.getBean("p",Person.class);
p.run();
p.fun("lalala");
p.ok("hncu", 66);

Cat c = ctx.getBean("cat", Cat.class);
c.run();

}
}


执行结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: