Spring中AOP

来源:互联网 发布:淘宝重复铺货怎么办 编辑:程序博客网 时间:2024/05/22 15:31

 

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;

 

publicclass Advice {

  

    publicvoiddoSomething()

    {

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

    }

   

}

 

package aop;

 

publicclass People {

  

    private Stringname;

 

    public String getName() {

        returnname;

    }

 

    publicvoidsetName(String name) {

        this.name = name;

    }

   

    public String greet()

    {

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

       

        returnname;

       

    }

   

}

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

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

  </bean>

 

  <beanid="method"class="aop.Advice"/>

<aop:config>

      <aop:aspect ref="method">

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

         <aop:beforemethod="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.............

 

 

给通知传递参数

实例:

publicclass Advice {

  

    privateint id;

   

   

    publicvoiddoSomething(int id)

    {

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

  }

}

 

publicclass People {

  

    private Stringname;

 

    public String getName() {

        returnname;

    }

 

    publicvoidsetName(String name) {

        this.name = name;

    }

   

    publicvoid greet(intid)

    {

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

       

    }

   

}

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

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

  </bean>

 

  <beanid="method"class="aop.Advice"/>

 

   <aop:config>

      <aop:aspect ref="method">

         <aop:pointcutexpression="execution(* aop.People.greet(int)) andargs(id)"id="greet"/>

         <aop:beforemethod="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传给了通知。

4 0
原创粉丝点击