Spring AOP AspectJ Annotation示例
在本教程中,我们将看到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