SpringAop的使用,使用xml和@注解配置两种方式






需要jar包:



 




springaop不起作用 springaop使用_xml


 



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     

       */     

      @Aspect     

      public class TestAOP {     

/**       





@SuppressWarnings("unused")      

@Pointcut("execution(* com.newer.service.impl.PersonServiceImpl.*(..))")      

private void anyMethod(){}      





/**      







@Before("anyMethod()")      

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

}      



/**      











@Before("anyMethod() && args(name)")      

public void doAccessCheckTwo(String name) {      



}



/**      







@AfterReturning("anyMethod()")      

public void doAccessReturning() {      



}      



/**      









@AfterReturning(pointcut="anyMethod()", returning="result")      

public void doAccessReturningTwo(String result) {      



}      



/**      







@After("anyMethod()")      

public void doAfter() {      



}      



/**      









@AfterThrowing("anyMethod()")      

public void doAfterThrowing() {      



}      



/**      







@AfterThrowing(pointcut="anyMethod()", throwing="e")      

public void doAfterThrowingTwo(Exception e) {      



}      



/**      









@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) {


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

//如果不执行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() {       



}       



/*** 后置通知(方法执行成功后执行) */       

public void doAccessReturning() {       



}       





/*** 最终通知 (finally块) */       

public void doAfter() {       



}       



/**       







public void doAfterThrowing() {       



}       



/**       







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

http://www.springframework.org/schema/context       

http://www.springframework.org/schema/context/spring-context-2.5.xsd      

http://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接口派生出来的方法)。