AOP

来源:互联网 发布:枣想核你在一起 淘宝 编辑:程序博客网 时间:2024/06/03 22:33

Spring另一个重要的思想就是面向切面编程,通俗的解释就是将一些类的功能作为切面,切入进我们的目标类中。不废话,直接上原理。

要了解aop首先了解代理模式。代理模式说白了就是代码的加强,比如对数据库的增删改查功能,他们都伴随着两个重复操作,就是commit提交和began开始。这个增删改查功能,我们就叫做目标类,开始提交的重复操作我们叫通知类,也就是传说中的切面。现在我们创建一个类,它和目标类实现同一个接口,并且引入目标类和通知类,在这个类中的增删改查功能都伴随着通知类的开始和提交操作。这种整合以后的类我们叫它代理类。这种模式叫做静态代理模式。

上面那种方式实际上很麻烦,反倒是增加了代码量。spring中的aop实现的底层原理是动态代理模式。动态代理模式有两个实现途径,一个是jdk的实现,一个是cglib的实现,jdk的实现中目标类和代理类实现了同一个接口。cglib中代理类是目标类的子类。spring根据代理类是否和目标类实现了同一个接口来决定使用哪种代理模式。

jdk代理模式实现类InvocationHandler 接口填充invoke接口。cglib实现了MethodInterceptor 接口。原理和操作都差不多。

Spring实现AOP有两种方法,一个是配置文件中声明方式,一个是在目标类中声明切面的注解方式。

配置文件方式:

 <aop:config >
  <!--  设置目标类 也就是切入点 -->
        <aop:pointcut expression="execution(* com.forlink.listener.SalaryManegerimpl.*(..))" id="pointcut"/>
<!-- 设置切面 -->
         <aop:aspect ref="transaction">
         <!-- 切面中的方法也就是通知类 -->
          <!-- before前置通知 -->
          <aop:before method="begin" pointcut-ref="pointcut"/>
          <!-- after-returning後置通知 -->
          <aop:after-returning method="commit" pointcut-ref="pointcut"/>
         </aop:aspect>
         <!-- 又一個切面 -->
         <aop:aspect ref="privilege">
          <!-- 環繞通知 -->
          <aop:around method="ifAccess" pointcut-ref="pointcut"/>
         </aop:aspect>
     </aop:config>

在通知类中声明切面方式:

@Controller
@Aspect//聲明切面
public class Transaction {

@Pointcut("execution(* com.forlink.listener.SalaryManegerimpl.*(..))")//目標類
private void transaction_point(){}//方法簽名,返回值必須為void,權限最好是private


@Before("transaction_point()")//前置通知
public void begin(){
System.out.println("begin");
}

@AfterReturning(value="transaction_point()")//後置通知
public void commit(){
System.out.println("commit");
}
}

0 0