当前位置

网站首页> 程序设计 > 开源项目 > 程序开发 > 浏览文章

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

作者:小梦 来源: 网络 时间: 2024-01-09 阅读:

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

引介增强

网友最爱