首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

SpringAop的施用

2012-11-22 
SpringAop的使用SpringAop的使用,使用xml和@注解配置两种方式需要jar包:AOP执行顺序:前置通知,是在方法前

SpringAop的使用

SpringAop的使用,使用xml和@注解配置两种方式
需要jar包: SpringAop的施用 AOP执行顺序:前置通知,是在方法前执行吗?环绕通知执行,进入方法...执行save()方法...@后置通知,是在方法后执行吗?最终通知 执行...@异常通知,程序出现异常了吗?(出现异常通知则后置通知不执行)环绕通知,退出方法...
========================================================
第一步:使用注解方式建立切面类,代码如下:
package com.newer.test;
import java.lang.reflect.Method;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;import org.aspectj.lang.reflect.MethodSignature;
/** * 测试Spring AOP机制 <br/> * 使用注解方式 配置切面 [@Aspect] * @author RSun * 2012-2-21上午12:07:17 */@Aspectpublic class TestAOP {

/**  * 声明一个切入点  <br/> */@SuppressWarnings("unused")@Pointcut("execution(* com.newer.service.impl.PersonServiceImpl.*(..))")private void anyMethod(){}
/** * 注解定义前置通知(方法执行前执行) <br/> * 需指明切入点 <br/> */@Before("anyMethod()")

public void doAccessCheck() {

        System.out.println("前置通知,是在方法前执行吗?");

}
/** * 前置通知,获取被拦截方法的参数 <br/> * 根据参数拦截相关方法,被拦截的方法参数类型需相同 <br/> * args(name) 里参数name必须和*Two(String name)参数名相同[name-name]<br/> * 需指明切入点 ,可以指定多个。 用 [||、&&]<br/> */@Before("anyMethod() && args(name)")public void doAccessCheckTwo(String name) {        System.out.println("获取传入参数的前置通知,传入参数name:" + name);

}

/** * 后置通知(方法执行成功后执行) <br/> * 需指明切入点 <br/> */@AfterReturning("anyMethod()")public void doAccessReturning() {        System.out.println("后置通知,是在方法后执行吗?");}
/** * 后置通知,获取被拦截方法的返回数据 <br/> * 注意参数的设定 <br/> * 需指明切入点 <br/> */@AfterReturning(pointcut="anyMethod()", returning="result")public void doAccessReturningTwo(String result) {        System.out.println("带返回值的后置通知,返回值result:"+result);}
/** * 最终通知 (finally块)<br/> * 需指明切入点 <br/> */@After("anyMethod()")public void doAfter() {        System.out.println("最终通知 执行...");}
/** * 例外通知(异常通知catch块) <br/> * 后置通知不执行(最终通知在异常通知前执行) <br/> * 需指明切入点 <br/> */@AfterThrowing("anyMethod()")public void doAfterThrowing() {        System.out.println("异常通知,程序出现异常了吗?");}
/** * 例外通知,获取异常 <br/> * 需指明切入点 <br/> */@AfterThrowing(pointcut="anyMethod()", throwing="e")public void doAfterThrowingTwo(Exception e) {        System.out.println("异常通知,异常:"+e);}
/** * 环绕通知 (用于权限判断)<br/> * 除方法名和参数名可修改外,其余不可变 <br/> * 需指明切入点 <br/> */@Around("anyMethod()")public Object doAround(ProceedingJoinPoint pjp) throws Throwable {

System.out.println("环绕通知 执行,进入方法...");

//获取被拦截的方法

Method method = ((MethodSignature)pjp.getSignature()).getMethod();

System.out.println("method:"+method.getName());

 

//获取拦截方法的参数

Object[] obj = pjp.getArgs(); 

for (Object object : obj) {

        System.out.println("AAA:"+object);

}
//必须执行这方法,如果后面有切面则先执行切面;//如果不执行proceed(),则后面的方法和和切面都不执行Object result = pjp.proceed(); //返回值,可以修改System.out.println("退出方法...");return result;
}

  * 解析: * @Pointcut("execution(* com.newer.service..*.*(..) ") * @Pointcut("execution(* com.newer.action..*.user*LoginOut())") * execution(* com.newer.service..*.*(..) <br/> * execution(1 com.newer.service..2.3(..) <br/> * 1. 表示返回值类型,例:java.lang.String,*号代表任何返回类型 ,!void表示必须有返回值 * 2. 表示类,* 号代表对所有类拦截 <br/> * 3. 表示方法,* 号代表所有方法 <br/> * 4. service.. 这两个点代表可以对service下的子包进行拦截 <br/> * 5. (..) 表示方法的参数可以可无,一个也行,多个亦可,例如:(java.lang.String,..) *  * 注解引用切入点的写法 * @Before("userLogin()") * @Before("userLogin() && userLoginOut()") * @Before("execution(* com.vveoss.examination.dailyExam.submitPaper(..))") 
 ======================================================== 
 第二步:xml方式的普通切面类,代码如下:package com.newer.test;
import org.aspectj.lang.ProceedingJoinPoint;
/** * 测试Spring AOP机制 <br/> * 使用xml方式配置 * @author RSun * 2012-2-21上午12:07:17 */public class TestAOPXml {
/*** 注解定义前置通知(方法执行前执行) */public void doAccessCheck() {        System.out.println("xml-----------前置通知,是在方法前执行吗?");}
/*** 后置通知(方法执行成功后执行) */public void doAccessReturning() {        System.out.println("xml-----------后置通知,是在方法后执行吗?");}
/*** 最终通知 (finally块) */public void doAfter() {        System.out.println("xml-----------最终通知 执行...");}
/** * 例外通知(异常通知catch块) <br/> * 后置通知不执行(最终通知在异常通知前执行) <br/> */public void doAfterThrowing() {        System.out.println("xml-----------异常通知,程序出现异常了吗?");}
/** * 环绕通知 (用于权限判断)<br/> * 除方法名和参数名可修改外,其余不可变 <br/> */public Object doAround(ProceedingJoinPoint pjp) throws Throwable {

System.out.println("xml-----------环绕通知 执行,进入方法...");

//必须执行这方法,如果后面有切面则先执行切面;

//如果不执行proceed(),则后面的方法和和切面都不执行

Object result = pjp.proceed();

System.out.println("xml-----------退出方法...");

return result;

}

 ======================================================== 
 第三步: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: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-2.5.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
<!-- 开启bean注解模式 --><context:annotation-config /> <!-- 扫描bean --><context:component-scan base-package="com.newer.service" /><!-- 开启aop注解  --><aop:aspectj-autoproxy /><!-- 切面交由Spring管理 --><bean id="testAop" class="com.newer.test.TestAOP" /> 
<!-- xml方式配置aop --><bean id="testAopXml" class="com.newer.test.TestAOPXml" /><aop:config>

<aop:aspect id="asp" ref="testAopXml">

<!-- 定义切面 --><aop:pointcut id="mycut" expression="execution(* com.newer.service.impl.PersonServiceImpl.*(..))" /><!-- 定义前置通知,关联切面和拦截方法doAccessCheck() --><aop:before pointcut-ref="mycut" method="doAccessCheck"/><!-- 定义后置通知 --><aop:after-returning pointcut-ref="mycut" method="doAccessReturning"/><!-- 异常通知 --><aop:after-throwing pointcut-ref="mycut" method="doAfterThrowing"/><!-- 最终通知 --><aop:after pointcut-ref="mycut" method="doAfter"/><!-- 环绕通知 --><aop:around pointcut-ref="mycut" method="doAround"/>

</aop:aspect>

</aop:config>
</beans>  
 总结:
  1. 配置好之后,可以使用junit测试,访问相关方法时会被触发。
  2. 需注意配置细节(只能拦截action、service和dao接口派生出来的方法)。


热点排行