zoukankan      html  css  js  c++  java
  • Spring Aop

     1,概念

    AOP,面向切面编程,实际上对OOP(面向对象编程)的一个补充。

    在面向对象编程的软件设计中,设计者会让不同的类去实现不同的方法,代码就分散到不同的类里面去了。降低了代码的复杂程度,提高了类的重用性。

    但是如果不同的类里面方法都需要实现某个功能,例如日志功能,那就必须在每个类都添加日志内容。如果将这个代码抽出来,单独建一个类,这样有提高了耦合。

    所以,这种在运行时候,将代码切入到指定类的指定方法,指定位置的的编程思想就是面向切面编程。

    2,AOP 术语

    Joinpoint(连接点):程序执行时的某个特定的点,在Spring中就是某一个方法的执行 。
    Pointcut(切点):spring中AOP的切点就是指一些方法的集合,而这些方法是需要被增强、被代理的。一般都是按照一定的约定规则来表示的,如正则表达式等。切点是由一类连接点组成。

    Aspect(切面):切面就是切点和连接点的结合。
    Advice(通知):就是在指定切点上要干些什么。
    Advisor(通知器):其实就是切点和通知的结合 。

    <aop:pointcut expression = " execution(*com.hella.aop.*.study(..))" id = ”study”/>

    第一个空格前是说明ret-type-pattern,空格后是说明name-pattern(param-pattern),具体说明如下:
    第一个*(ret-type-pattern), 表示任意返回值类型
    第二个和第三个*(name-pattern), 第二个包名通配,第三个方法名通配
    最后二个.. 表示通配方法可以有0个或多个参数

    3,通知的类型

    前置通知:在一个方法执行之前,执行通知。

    后置通知:在一个方法执行之后,不考虑其结果,执行通知。

    返回后通知:在一个方法执行之后,只有在方法成功完成时候,才能执行通知。

    抛出异常后通知:在一个方法执行之后。只有在方法退出抛出异常时,才能执行通知。

    环绕通知:在建议方法调用之前和之后,执行通知。

    4,Aop 实现

    方法1:基于XML 实现

    public interface Student {

        public void study();

        public void play();

    }

    public class ForeignStudent implements Student {

        @override

         public void study(){

              system.out.println("foreign students will study");

        }

        @override

        public void play(){

             system.out.print("foreign students will play");

        }

    }

    public class ChineseStudent implements Student{

        @override

        public void study(){

            system.out.print("chinese students will study");

          }

        @override

       public void play(){

           system.out.print("chinese students will play");

        }

    }

    定义切面类:

    public class AopAspect {

        public void beforeStudy(){

            system.out.print("wash hand");

        }

        public void beforePlay(){

            system.out.print("put on sport shoes");

        }

        public void afterPlay(){

            system.out.print("wash hand");

        }

    }

    在XML 配置文件中,首先需要实例化目标对象。

    <bean id = "foreignStudent" class = "com.hella.aop.ForeignStudent"></bean>

    <bean id  = "chineseStudent" class = "com.hella.aop.chineseStudent"></bean>

    然后,需要实例化切面类。

    <bean id = "aopAspect" class = "com.hella.aop.AopAspect"></bean>

    其次,配置切入对象(point cut),一些方法的集合

    <aop:config>

        <aop:pointcut expression = " execution(*com.hella.aop.*.study(..))" id = "study"/> //要切入的对象

        <aop:pointcut expression = "execution(*com.hella.aop.*.play(..))" id = "play"/>

         <aop:aspect id = "ha" ref = "aopAspect" > 

               <aop:before method="beforeStudy()" pointcut-ref="study"/><!-- 之前通知 -->
               <aop:before method="beforePlay()" pointcut-ref="play"/><!-- 之前通知 -->

               <aop:after method="afterPlay()" pointcut-ref="play"/><!-- 之后通知 -->

              // <aop:after-returning   返回后通知

              // <aop:after-throwing   异常通知

             // <aop:around   环绕通知

         </aop:aspect>

    </aop:config>

    测试:

    public class test {

        public static void main(String[] args){

             ApplicationContext context = new classPathApplicationContext("beans.xml");

             Student  s = (Student )context.getBean("foreignStudent");

             s.study();

             s.play();

            Student s =  (Student) Context.getBean("chineseStudent");

            s.study();

            s.play();

        }

    }

    打印结果:wash hand

                      foreign student will study

                      put on sport shoes

                      foreign student will play

                      wash hand

                 

                     wash hand

                     chinese student will study

                     put on sport shoes

                     chinese student will play

                     wash hand

    方法2:基于注解

    public interface Student {

        public void study();

        public void play();

    }

     @Component     //自动扫描并且实例化

    public class ForeignStudent implements Student {

        @override

         public void study(){

              system.out.println("foreign students will study");

        }

        @override

        public void play(){

             system.out.print("foreign students will play");

        }

    }

     @Component     //自动扫描并且实例化

    public class ChineseStudent implements Student{

        @override

        public void study(){

            system.out.print("chinese students will study");

          }

        @override

       public void play(){

           system.out.print("chinese students will play");

        }

    }

    定义切面类:

     @Aspect   //声明该类是切面类

     @Component     //自动扫描并且实例化

    public class AopAspect {

        @Before(“execution(*.com.hella.aop.*study(..))”)

        public void beforeStudy(){

            system.out.print("wash hand");

        }

       @Before("execution(*.com.hella.aop.*.play(..))")

        public void beforePlay(){

            system.out.print("put on sport shoes");

        }

        @After("execution(*.com.hella.aop.*.play(..))")

        public void afterPlay(){

            system.out.print("wash hand");

        }

    }

     //@AfterReturnning   返回通知

    //@AfterThrowing       抛出异常通知

    //@Around                 环绕通知

    在配置文件Bean.xml中,首先需要引入aop的命名空间

    xmlns:aop="http://www.springframework.org/schema/aop"

    然后,

     <!-- 自动扫描包下的类,并将其实例化。多个包之间用,隔开 -->        

    <context:component-scan base-package="com.hella.aop"></context:component-scan>

    <!-- 配置文件中启动AspectJ的注解功能 ,默认是false,要将其改为true -->

    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>


    测试:

    public class test {

        public static void main(String[] args){

             ApplicationContext context = new classPathApplicationContext("beans.xml");

             Student  s = (Student )context.getBean("foreignStudent");

             s.study();

             s.play();

            Student s =  (Student) Context.getBean("chineseStudent");

            s.study();

            s.play();

        }

    }

           

    打印结果:wash hand

                      foreign student will study

                      put on sport shoes

                      foreign student will play

                      wash hand

                 

                     wash hand

                     chinese student will study

                     put on sport shoes

                     chinese student will play

                     wash hand

                     

  • 相关阅读:
    Python入门11 —— 基本数据类型的操作
    Win10安装7 —— 系统的优化
    Win10安装6 —— 系统的激活
    Win10安装5 —— 系统安装步骤
    Win10安装4 —— 通过BIOS进入PE
    Win10安装2 —— 版本的选择与下载
    Win10安装1 —— 引言与目录
    Win10安装3 —— U盘启动工具安装
    虚拟机 —— VMware Workstation15安装教程
    Python入门10 —— for循环
  • 原文地址:https://www.cnblogs.com/pickKnow/p/9513148.html
Copyright © 2011-2022 走看看