Spring中AOP

 

AOP

     在软件开发中,分布于应用中多处理的功能被称为横切关注点,通常,横切关注点从概念上讲是与应用逻辑相分离的,将横切关注点与业务逻辑相分离正是面向切面编程(AOP)要解决的问题.

依赖注入有利于对象之间的解耦,而AOP可以实现横切关注点与它们所影响的对象之间的解耦。横切关注点常常应用在日志、事务管理、缓存等。

     在面向切面的编程中,横切点就是一个通用的功能,也可以称作为切面,该功能可以再任何地方使用,而无需修改受影响的类。这样做的好处:1.关注点集中一处,而不是分散开来2.服务模块简单化

 

AOP中的术语

切面(aspect):在应用程序中一个通用的功能

通知(advice):可以理解为是切面的一个具体实现,通常使用Java编写,常用的通知:前置通知(before)、后置通知(after)、环绕通知(around)、返回通知(after-returning)、异常通知(after-throwing)

 

切点(pointcut):指切面或者是通知所存在的位置,这个位置就是切点。

连接点(joinpoint):将通知放在切点的一个时机,例如:方法前、方法后等。

织入(weaving):将切面应用到目标对象创建新的代理对象的过程。

引入(introduction):允许我们向现有类添加新的属性或方法。主要通过创建通知来实现。

 

 

在Spring中需要使用AspectJ的切点表达式来编写切点。


其中execution指示器()是定义切点的最主要指示器,在此基础上联合其它的指示器来限定切点。

例如:execution(*  aop.People.getName(..))

类People加上方法getName  ,用(..)表示方法的参数,

“ * ”表示的是方法的任意返回类型.

execution(* aop.People.getName(..)) && within(aop1.*)

&&表示并且 ,aop1.*表示aop1包下的任意类方法,那么整个表达式表示当aop.People.getName(..)方法和aop1包下任意类的方法同时执行时,才会执行execution,即相应的通知。

类似的还有”||”、”!”符号。

在Spring中还有一个bean指示器,bean含有一个id号,用于限定bean。例如:execution(* aop.People.getName(..)) and bean(p)

 

AOP在XML中声明

 

实例:

package aop;

 

public class Advice {

  

    public voiddoSomething()

    {

        System.out.println("hello.......");

    }

   

}

 

package aop;

 

public class People {

  

    private String name;

 

    public String getName() {

        return name;

    }

 

    public voidsetName(String name) {

        this.name = name;

    }

   

    public String greet()

    {

        System.out.println(name+".............");

       

        return name;

       

    }

   

}

<bean  id="p"class="aop.People">

     <property name="name" value="zhangsan"></property>

  </bean>

 

  <bean id="method" class="aop.Advice"/>

<aop:config>

      <aop:aspect  ref="method">

         <aop:pointcut expression="execution(* aop.People.greet()) and bean(p)"id="greet"/>

         <aop:before method="doSomething" pointcut-ref="greet"/>

      </aop:aspect>

   </aop:config>

 

ApplicationContextac=new ClassPathXmlApplicationContext("aop/bean.xml");

       

        People p=ac.getBean("p", People.class);

        p.greet();

结果:hello .......

zhangsan.............

 

 

给通知传递参数

实例:

public class Advice {

  

    private int id;

   

   

    public voiddoSomething(int id)

    {

        System.out.println("hello......."+id);

  }

}

 

public class People {

  

    private String name;

 

    public String getName() {

        return name;

    }

 

    public voidsetName(String name) {

        this.name = name;

    }

   

    public void greet(int id)

    {

        System.out.println(name+".............");

       

    }

   

}

<bean id="p" class="aop.People">

     <property name="name" value="zhangsan"></property>

  </bean>

 

  <bean id="method" class="aop.Advice"/>

 

   <aop:config>

      <aop:aspect  ref="method">

         <aop:pointcut expression="execution(* aop.People.greet(int)) and args(id)"id="greet"/>

         <aop:before method="doSomething" pointcut-ref="greet" arg-names="id" />

      </aop:aspect>

   </aop:config>

   

    </beans>

 

ApplicationContextac=new ClassPathXmlApplicationContext("aop/bean.xml");

       

        People p=ac.getBean("p", People.class);

      p.greet(1);

结果:hello .......1

zhangsan.............

由结果可知,目标方法中的参数id传给了通知。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值