Spring AOP(3)
在1,2节里面我们已经大致了解了AOP的工作原理,以及Spring下AOP的配置与实现,BeanNameAutoProxyCreator,DefaultAdvisorAutoProxyCreator已经部分简化了AOP配置,然而还是很繁琐:
首先要编写xxxAdvice类(需要自己实现MethodBeforeAdvice、MethodAfterAdvice、ThrowsAdvice、MethodInterceptor接口之一),然后还要在xml中配置Advisor,还要在Advisor中注入Advice,最后还要将Advisor加入ProxyFactoryBean、BeanNameAutoProxyCreator或者DefaultAdvisorAutoProxyCreator中。
而Spring2.x以后引入了@AspectJ注解,可以通过Java5的注解以AspectJ的语法在Spring中配置AOP了,使用@AspectJ后,这一切都将变得异常简单:
只需要定义一个Aspect类,在Aspect中声明Advice(可以同时声明多个),然后在xml中配置这个Aspect,最后添加一行<aop:aspectj-autoproxy/>就可以搞定。
这种方式更加灵活、简单。
下面是一个Demo:
//定义一个切面@Aspectpublic class LoggerAspect{ @Before("excution(* Service.login(username,..))") public void logBefore(String username){ System.out.println("[Logger] User " + username + "try to login"); }}
<!--定义切面--><bean id="loggerAspect" .../><!--配置Aspect支持--><aop:aspectj-autoproxy/>
@AfterReturning("excution(* Service.login(username,..))")public void logSuc(String username){ System.out.println("[Logger] User " + username + "login successfully");}
@Aspectpublic class SecurityAspect{ @Around("excution(* Service.login(username,..))") public Object securityCheck(ProceedingJionPoint pjp) throws Throwable{ //调用之前进行用户检查 String username=(String)pjp.getArgs()[0]; if(!"zhangsan".equals(username)){ //对除zhangsan之外的用户开放 return pjp.proceed(); } //抛出异常,禁止zhangsan登陆 throw new RuntimeException("Reject login!"); }}
@Aspectpublic class LoggerAspect{ //声明切入点 @Pointcut("excution(* Service.login(username,..))") public void login(){}; @Before(value="login()") public void logBefore(String username){ System.out.println("[Logger] User " + username + "try to login"); } @AfterReturing(value="login()") public void logSuc(String username){ System.out.println("[Logger] User " + username + "login successfully"); } @AfterThrowing(pointcut="login()",throwing="e") public void logFailure(RuntimeException e){ System.out.println("[Logger] Exception:" + e.getMessage()); }}