<spring 3.x企业应用开发实战>读书笔记-基于注解和声明式的aop

来源:互联网 时间:1970-01-01

@AspectJ配置切面

编程方式实现

public class Waiter {public void check(String name){System.out.println("waiter说:结账?"+name);}public void serve(String name){System.out.println("waiter说:要点什么?"+name);}}
import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;@Aspectpublic class PreGreeting {@Before("execution(* serve(..))")public void beforeGreeting(){System.out.println("how are you!");}}

@Before注解表示前置增强,后面的切点表达式表示在目标类的serve()方法织入增强,serve()方法可以带任意的传入参数和任意的返回值。
PreGreeting类通过注解,将切点,增强类型和增强的横切逻辑组合在一起。PreGreeting类相当于上一篇中的BeforeAdvice(增强),NameMatchMethodPointcut(切点)DefaultPointcutAdvisor(切面)三者联合表达的信息。

Waiter waiter=new Waiter();AspectJProxyFactory factory=new AspectJProxyFactory();factory.setTarget(waiter);//设置目标类factory.addAspect(PreGreeting.class);//添加切面Waiter proxy=factory.getProxy();proxy.serve("TheViper");proxy.check("TheViper");
how are you!waiter说:要点什么?TheViperwaiter说:结账?TheViper

通过配置使用

<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" xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><aop:aspectj-autoproxy/><bean id='waiter' class='aspectj.Waiter'/><bean class='aspectj.PreGreeting'/></beans>
  • 引用aop命名空间

xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="... http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
  • <aop:aspectj-autoproxy/>自动为spring容器中那些匹配@AspectJ切面的Bean创建代理,完成切面织入

ApplicationContext ctx=new ClassPathXmlApplicationContext("beans.xml");Waiter waiter=(Waiter)ctx.getBean("waiter");waiter.serve("TheViper");waiter.check("TheViper");

使用的时候,直接获取bean操作就可以了,不用像前面还要创建AspectJProxyFactory,设置好代理才能用。

schema配置切面

配置命名切点

需要引入aspectjweaver

public class GreetBefore {public void say(String name){System.out.println("hallo!"+name);}}

增强不用像上一篇中那样,需要继承特定类或实现特定接口。

<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" xmlns:p="http://www.springframework.org/schema/p"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><bean id='waiterTarget' class='com.Waiter'/><bean id='greetBefore' class='schema.GreetBefore'/><aop:config><aop:pointcut expression="target(com.Waiter) and execution(* check(..)) and args(name,..)" id="servePointcut"/><aop:aspect ref="greetBefore"><aop:before method="say" pointcut-ref="servePointcut"/></aop:aspect></aop:config></beans> 

匹配Waiter类中的check()方法。

  • 需要引入aop命名空间

xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="... http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"
  • <aop:aspect>定义切面,其内部可以定义多个增强,ref属性指定引用的具体增强

  • <aop:before>声明了一个前置增强,通过pointcut-ref属性引用切点,method属性指定增强中哪个方法用于具体的增强行为

  • <aop:pointcut>定义切点,expression属性设置切点表达式,其语法和@AspectJ中的语法完全相同。

public class Waiter {public void check(String name){System.out.println("waiter说:结账?"+name);}public void serve(String name){System.out.println("waiter说:要点什么?"+name);}}
ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");Waiter waiter=(Waiter)ctx.getBean("waiterTarget");waiter.serve("TheViper");waiter.check("TheViper");
waiter说:要点什么?TheViperhallo!TheViperwaiter说:结账?TheViper

配置顺序问题

命名切点只能被当前<aop:aspect>内定义的元素访问到,<aop:config>中的配置顺序必须是<aop:pointcut>=><aop:advisor>=><aop:aspect>

各种增强类型

后置增强

<aop:config>...<aop:aspect ref="greetBefore"><aop:after-returning method="sayEnjoy" pointcut='target(com.Waiter) and execution(* serve(..))'/></aop:aspect></aop:config>

环绕增强

<aop:config>...<aop:aspect ref="greetBefore"><aop:around method="aroundMethod" pointcut='execution(* serve(..)) and within(com.Waiter))'/></aop:aspect></aop:config>
public void aroundMethod(ProceedingJoinPoint pjp){//pjp可以访问到环绕增强的连接点信息...}

抛出异常增强

<aop:config>...<aop:aspect ref="greetBefore"><aop:after-throwing method="afterThrowingMethod" pointcut='target(com.Waiter) and execution(* serve(..))' throwing='exception'/></aop:aspect></aop:config>
public void afterThrowingMethod(Exception exception){...}

throwing属性声明需要绑定的异常对象,指定的异常名必须和增强方法对应的传入参数一致

final增强

<aop:config>...<aop:aspect ref="greetBefore"><aop:after method="afterMethod" pointcut='execution(*com.Waiter. serve(..))'/></aop:aspect></aop:config>

引介增强

相关阅读:
Top