zoukankan      html  css  js  c++  java
  • spring入门(四)【面向切面编程】

    开发过程中很多时候会用到日志、事务等操作,这些操作如果要写在业务代码中会相当麻烦,这时就会用到面向切面编程(AOP),AOP作为一种编程思想,和OOP有着不同的侧重点,面向对象侧重于万事万物皆对象,而面向切面编程则侧重于事务的一个方面。在面向切面编程过程中有几个比较重要的概念:切面、切点、连接点、通知,

    通知:描述了切面要完成的工作,例如,要向某个方法注入日志功能,这里的日志功能就是通知;通知分为5种:Before、After、After-returning、After-throwing、Around

    切点:定义了通知被应用的地方,如,某个类上的某个方法;例如,在test类的print方法;

    切面:横切关注点被模块化的类,由通知和切点组成,换句话来说切面定义了要向目标程序注入的全部内容;规定了在目标方法上执行什么样的动作;

    连接点:程序执行过程中切面可以被插入的一个点,如方法调用、成员变量初始化,在spring中只支持方法调用;

    面向切面编程有两种实现方式,一种是预编译,另一种是动态代理,AspectJ属于预编译,springAOP属于运行期动态代理方式。spring实现了对AspectJ的支持。下面看springAOP和AspectJ的使用方式,

    springAOP

    这里使用配置文件的方式,实现springAOP,看配置文件,

        <aop:config>
            <!--声明一个切面类  可以有多个-->
            <aop:aspect id="myAspect" ref="aspect">
                <!--声明一个切点-->
                <aop:pointcut id="point1" expression="execution(* com.cn.study.day6.Test.*(..))"/>
                <!--通知-->
                <aop:before method="before" pointcut-ref="point1" />
                <aop:around method="around" pointcut-ref="point1"/>
            </aop:aspect>
            
        </aop:config>
        <!--配置切面类-->
        <bean id="aspect" class="com.cn.study.day6.Aspect"></bean>


    要配置AOP,在spring中使用了<aop:config>标签,在这个标签中可以配置多个切面标签(<aop:aspect>),每个切面代表了一种横切关注点,从前面的阐述中可以知道一个切面包含两部分,一个是切点,另一个是通知,在<aop:aspect>标签中定义切点(<aop:pointcut>)和通知(aop:before 前置通知),在切点中配置了通知被应用的位置,即匹配Test类的任何方法(execution(* com.cn.study.day6.Test.*(..))),在通知标签中配置了执行目标方法前通知,切点是point1;下面看具体的切面类,

    package com.cn.study.day6;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    
    //切面类
    public
    class Aspect { //前置通知调用的方法 public void before(){ System.out.println("我是前置通知!"); } public Object around(ProceedingJoinPoint jp){ System.out.println("我是环绕通知!"); Object object=null; try { System.out.println("方法执行前"); object = jp.proceed(); System.out.println("方法执行之后"); } catch (Throwable e) { // TODO Auto-generated catch block e.printStackTrace(); } return object; } }

    切面类中的方法要和通知中method属性的方法名字保持一致,下面是目标方法,

    package com.cn.study.day6;
    
    import org.springframework.cache.annotation.Cacheable;
    import org.springframework.stereotype.Component;
    @Component
    public class Test {
    
        public void method1(){
            System.out.println("业务方法!");
        }
    }

    上面是一个简单的业务方法,
    总结下这个切面类的含义,即在执行com.cn.study.day6.Test类中的任何方法之前都会首先执行com.cn.study.day6.Aspect切面类中的before方法,看打印结果,

    我是前置通知!
    业务方法!

    结果显示首先执行了切面类中的before方法,然后执行的是目标类中的method1方法。

    上面就完成了一个面向切面编程的例子,我们实现的是在方法被调用之前实现横切,那么面向切面编程到底有什么用处呢?我们在最后进行说明,接着看AspectJ

    AspectJ

    AspectJ是AOP的另一种实现,要使用AspectJ必须打开自动代理,如下

    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

    这是对AspectJ的自动代理,然后就可以使用AspectJ了,看下面的切面类

    package com.cn.study.day7;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.Pointcut;
    import org.springframework.stereotype.Component;
    @Component
    @Aspect
    public class AspectTest {
        //前置通知调用的方法  通知
        @Before("pointCut1()")
        public void before(){
            
            System.out.println("我是前置通知!");
            
        }
        //切点
        @Pointcut("execution(* com.cn.study.day7.Test.*(..))")
        public void pointCut1(){
            
        }
    
    }

    由于加了@AspectJ的类无法被自动识别,所以需要加载@Component注解,有了这两个注解之后,此类便是一个切面类了,在切面类里可以声明切点和通知,我们定义了一个pointCut1的切点,此方法的返回值必须是void,此切点对com.cn.study.day7.Test下的所有方法有效,接着使用@Before定义了一个前置通知,且使用的切点为pointCut1(),打印结果如下,

    我是前置通知!
    业务方法!

    上面便完成了使用AspectJ的切面编程;另,在定义通知的之后也可以直接使用表达式(execution(* com.cn.study.day7.Test.*(..)))而不必引用某个切点,引用某个切点的好处是,在定义了切点之后可以复用。

    综上,是两种实现AOP的配置,AOP的使用场景是在不破坏原有代码的基础上,增加新的功能,比如日志、事务控制,使用AOP可以很好地减少代码的侵入,在原有代码不变的基础上轻松实现日志、事务控制、权限控制等。这两种方式在实际开发过程当中使用的都很广泛,具体使用哪种方式可根据自己的情况而定。

    有不足之处,欢迎指出!

  • 相关阅读:
    《你的灯还亮着吗》读后感1
    找"1"
    阅读计划---《梦断代码》3
    阅读计划---《梦断代码》2
    个人工作总结(10)
    个人工作总结(9)
    个人工作总结(8)
    个人工作总结(7)
    学习进度条
    个人工作总结(6)
  • 原文地址:https://www.cnblogs.com/teach/p/5839427.html
Copyright © 2011-2022 走看看