Spring AOP AspectJ Annotation示例

时间:2020-02-23 14:35:36  来源:igfitidea点击:

在本教程中,我们将看到Spring AOP AspectJ注释示例。

如果我们不熟悉Spring AOP术语,我们可能会通过Spring Apposented编程(AOP)教程。

以下是我们将用于实施Spring AOP的AspectJ注释。

@aspect:将类视为方面。

用于创建建议的注释是:@Before:@Before注释用于在建议之前创建。
它在实际方法执行之前执行(加入点)@AfterReturning:此注释用于创建返回建议。
在没有任何异常的情况下,执行方法执行后执行。

@AfterTrapray:此注释用于创建抛出建议后,它会通过抛出异常来执行方法。

@After:此注释用于在建议之后创建,它在方法执行后执行,无论结果如何。

@Around:此注释用于创建围绕建议,它在连接点之前和之后执行。

这可能是令人困惑的,但是一旦实现一个例子,就会清楚。

@Before :

让我们说你有一些业务逻辑类(BusinessLogic.java),我们希望在执行此类的GetBusinessLogic方法之前进行日志记录。

package org.igi.theitroad;
 
public class BusinessLogic {
 
 public void getBusinessLogic() {
  System.out.println("*");
  System.out.println("In Business Logic method");
  System.out.println("*");
 }
}

现在我们将创建aspect类

package org.igi.theitroad;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
 
@Aspect
public class LoggingAspect {
 
 @Before("execution(* org.igi.theitroad.BusinessLogic.getBusinessLogic(..))")
 public void loggingBeforeBusinessLogic(JoinPoint joinPoint) {
 
  System.out.println("loggingBeforeBusinessLogic() is running!");
  System.out.println("Before execution of method : " + joinPoint.getSignature().getName());
 }
 
}

执行(* org.igi.theitroad.businessLogic.getBusinessLogic(..))是PointCut表达式。
它表示在对BusinessLogic类的GetBusinessLogic方法进行预测之前的MolegingBeforeBusinessLogic的执行。
在Spring-config.xml中,允许在spring-config.xml中执行XML Configuation。

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 http://www.springframework.org/schema/aop 
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
 
 <aop:aspectj-autoproxy 
 <bean id="businessLogic" class="org.igi.theitroad.BusinessLogic">
 </bean>
 <!-- Aspect -->
 <bean id="logAspect" class="org.igi.theitroad.LoggingAspect" 
 
</beans>

创建名为springaopmain的主类以执行该应用程序

package org.igi.theitroad;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
 
public class SpringAOPMain {
 
    public static void main(String[] args) {
        ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml");
        BusinessLogic businessLogic = (BusinessLogic) appContext.getBean("businessLogic");
        businessLogic.getBusinessLogic();      
    }
}

运行上面的程序时,我们将得到以下输出:

May 21, 2015 10:01:14 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@24174be7: startup date [Thu May 21 22:01:14 IST 2015]; root of context hierarchy
May 21, 2015 10:01:14 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
loggingBeforeBusinessLogic() is running!
Before execution of method : getBusinessLogic
*
In Business Logic method
*

@After:

我正在使用@After注释方法替换@Before方法。
此方法将在执行实际业务逻辑之后执行,因此LoggingAppe.java将看起来像这样。

package org.igi.theitroad;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;
 
@Aspect
public class LoggingAspect {
 
@After("execution(* org.igi.theitroad.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogic(JoinPoint joinPoint) {
 
  System.out.println("loggingAfterBusinessLogic() is running!");
  System.out.println("After execution of method : " + joinPoint.getSignature().getName());
 }
}

当我们再次运行springaopmain.java时,我们将得到以下输出:

May 21, 2015 10:24:26 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@75783d33: startup date [Thu May 21 22:24:26 IST 2015]; root of context hierarchy
May 21, 2015 10:24:26 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
*
In Business Logic method
*
loggingAfterBusinessLogic() is running!
After execution of method : getBusinessLogic

正如我们在上面的输出中看到的,LoggingAfterBusinessLogic在GetBusinessLogic方法之后执行

@Afterreturn:

我在上面的loggingaspect.java中用@Afterreturn替换@After。
此方法在执行实际业务逻辑之后执行,但仅在成功返回时才执行。

package org.igi.theitroad;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;
 
@Aspect
public class LoggingAspect {
 
@AfterReturning("execution(* org.igi.theitroad.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogic(JoinPoint joinPoint) {
 
  System.out.println("loggingAfterBusinessLogic() is running!");
  System.out.println("After execution of method : " + joinPoint.getSignature().getName());
 }
}

当我们再次运行springaopmain.java时,我们将得到以下输出:

May 21, 2015 10:24:26 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@75783d33: startup date [Thu May 21 22:24:26 IST 2015]; root of context hierarchy
May 21, 2015 10:24:26 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
*
In Business Logic method
*
loggingAfterBusinessLogic() is running!
After execution of method : getBusinessLogic

@Afterthray:

允许使用@AfterTrapring注释添加一种方法。
如果GetBusinessLogic方法中发生任何异常,则执行它。
LoggingAppect.java.

package org.igi.theitroad;
 
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
 
@Aspect
public class LoggingAspect {
 
 @AfterReturning("execution(* org.igi.theitroad.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogic(JoinPoint joinPoint) {
 
  System.out.println("loggingAfterBusinessLogic() is running!");
  System.out.println("After execution of method : " + joinPoint.getSignature().getName());
 }
 
 @AfterThrowing("execution(* org.igi.theitroad.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogicException(JoinPoint joinPoint) {
 
  System.out.println("Exception occurred in getBusinessLogic method");
  
 }
 
}

现在从GetBusinessLogic投掷RuntimeException来测试@AfterTrakring异常。
BusinessLogic.java.

package org.igi.theitroad;
 
public class BusinessLogic {
 
 public void getBusinessLogic() {
  System.out.println("*");
  System.out.println("In Business Logic method");
  System.out.println("*");
  throw new RuntimeException();
 }
}

运行springaopmain.java时,我们将得到以下输出:

May 21, 2015 10:34:55 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@739474: startup date [Thu May 21 22:34:55 IST 2015]; root of context hierarchy
May 21, 2015 10:34:55 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
*
In Business Logic method
*
Exception occurred in getBusinessLogic method
Exception in thread "main" java.lang.RuntimeException
 at org.igi.theitroad.BusinessLogic.getBusinessLogic(BusinessLogic.java:9)
 at org.igi.theitroad.BusinessLogic$$FastClassBySpringCGLIB$d288cb4.invoke()
 at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
 at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
 at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
 at org.igi.theitroad.BusinessLogic$$EnhancerBySpringCGLIB$fbd989f.getBusinessLogic()
 at org.igi.theitroad.SpringAOPMain.main(SpringAOPMain.java:10)

正如我们可以看到LoggingAfterBusinessLogicexception,因为业务逻辑存在异常。

@Around:

使用@Around的方法将在执行业务逻辑之前和之后调用。
我们需要调用RequestingJoInPoint的引用并调用继续执行实际业务逻辑的方法。

package org.igi.theitroad;
 
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
 
@Aspect
public class LoggingAspect {
 
 @Around("execution(* org.igi.theitroad.BusinessLogic.getBusinessLogic(..))")
 public void loggingAroundBusinessLogic(ProceedingJoinPoint joinPoint) throws Throwable {
  System.out.println("Before calling actual business logic"); //Before running actual business logicic
  joinPoint.proceed(); //business logic method get executed 
  System.out.println("After calling actual business logic"); //After running actual business logic
 }
}

运行springaopmain.java时,我们将得到以下输出:

May 21, 2015 11:04:10 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@739474: startup date [Thu May 21 23:04:10 IST 2015]; root of context hierarchy
May 21, 2015 11:04:10 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
Before calling actual business logic
*
In Business Logic method
*
After calling actual business logic