• 34.Spring-Aop.md


    http://blog.csdn.net/bigtree_3721/article/details/50759843


    目录

    1.概念

    1.1概念

    AOP是Spring提供的关键特性之一。AOP即面向切面编程,是OOP编程的有效补充。使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。这些系统性的编程工作都可以独立编码实现,然后通过AOP技术切入进系统即可。从而达到了 将不同的关注点分离出来 的效果。
    

    AOP相关的概念

    • Aspect :切面,切入系统的一个切面。比如事务管理是一个切面,权限管理也是一个切面;

    • Join point :连接点,也就是可以进行横向切入的位置;

    • Advice :通知,切面在某个连接点执行的操作(分为: Before advice , After returning advice , After throwing advice , After (finally) advice , Around advice );

    • Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方;

    1.2 AOP 的实现原理

    AOP分为静态AOP和动态AOP。静态AOP是指AspectJ实现的AOP,他是将切面代码直接编译到Java类文件中。动态AOP是指将切面代码进行动态织入实现的AOP。Spring的AOP为动态AOP,实现的技术为: JDK提供的动态代理技术 和 CGLIB(动态字节码增强技术) 。尽管实现技术不一样,但 都是基于代理模式 , 都是生成一个代理对象 。

    2.开发步骤

    2.1注解方式实现AOP

    2.1.1不同类型注解的作用

    2.1.1.1拦截表达式

    使用注解,必须使用拦截表达式。告诉aop中哪些类或者哪些函数是需要被拦截的,也就是切入点。表达式的范例如下(一定不要写错,例如空格和括号一类

    @Pointcut(value = "execution(* per.liyue.aop.annotion..(..))")
    其中,execution是固定写法括号中的第一个和其后的一个空格一定不能写错。后面是包和对应的类。如果拦截整个类所有方法那么用匹配,如果指定方法那么要写明。拦截的方法如果没有参数可以空括号表示,如果有可以用..来表示有参数。

    2.1.1.2注解类型

    在各种类型的注解中指定切入点

    • @Around 环绕通知,环绕在切入点的前后
      这个注解相对其他不一样,在函数中执行实际的方法,在方法前后完成业务切入
    • @Before 前置通知,在切入点前执行
    • @After 后置通知,在切入点后执行,无论是否有异常都执行
    • @AfterReturning 返回通知,在执行切入点后执行,如果有异常则不执行
    • @AfterThrowing 遇到异常时候执行

    2.1.2各种类型注解顺序图

    2.1.3实例

    2.1.3.1引入相关jar包

    这几个jar包是必须有,而且要注意版本匹配,如果aspectj的两个相关jar包版本过低,最终运行时候会报各种错误。

    例如:error at ::0 can't find referenced pointcut.

    2.1.3.2需要抽离的业务类

    注意注解@Component是不能少的,因为要注入IOC容器

    package per.liyue.aop.annotion;
    
    /**
     * Created by liyue on 2016/11/17.
     */
    //普通的接口类
    public interface IUserDao
    {
        public void save();
    }
    
    package per.liyue.aop.annotion;
    
    import org.springframework.stereotype.Component;
    
    /**
     * Created by liyue on 2016/11/17.
     */
    @Component//将类对象注入IOC容器
    public class UserDao implements IUserDao
    {
        @Override
        public void save()
        {
            System.out.println("保存数据!");
        }
    }
    

    2.1.3.3切面类

    package per.liyue.aop.annotion;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    /**
     * Created by liyue on 2016/11/17.
     */
    @Component  //指定当前类是组件,加入IOC容器
    @Aspect     //指定当前类是切入面
    public class Aop
    {
    
        /*
        * 指定切入点
        * */
        //注解表达式:配置需要拦截的方法,用*表示所有,下面的表达式表示per.liyue.aop.annotion.UserDao类下的所有函数,没有参数可以空括号,有参数用..代替
        @Pointcut(value = "execution(* per.liyue.aop.annotion.*.*(..))")
        public void aspPointCut(){}
    
        @Before("aspPointCut()")//指定切入点
        public void beforeFun()
        {
            System.out.println("开始之前执行业务。。。");
        }
    
        @After("aspPointCut()")//指定切入点
        public void afterFun()
        {
            System.out.println("结束之前执行业务...");
        }
    
        @AfterReturning("aspPointCut()")//指定切入点
        public void afterReturningFun()
        {
            System.out.println("返回之后执行业务...");
        }
    
    
        @AfterThrowing("aspPointCut()")//指定切入点
        //没有异常的时候不会执行的
        public void afterThrowingFun()
        {
            System.out.println("当捕获异常后执行...");
        }
    
        @Around("aspPointCut()")//指定切入点,
        public void arroundFun(ProceedingJoinPoint pj) throws Throwable
        {
            System.out.println("环绕前执行的业务...");
            Object obj = pj.proceed();
            System.out.println("环绕后执行的业务...");
        }
    
    
    }
    

    2.1.3.4配置xml文件

    注意这里需要开启aspect和aop的扫描,否则会报错

    <?xml version="1.0" encoding="UTF-8"?>
    <!--增加aop命名空间-->
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
    
            <context:component-scan base-package="per.liyue.aop.annotion"></context:component-scan>
            <!--开启aop的注解方式-->
            <aop:config proxy-target-class="true"></aop:config>
            <!--开启切面编程-->
            <aop:aspectj-autoproxy proxy-target-class="false"></aop:aspectj-autoproxy>
    
    </beans>
    
    

    2.1.3.5调用实现

    package per.liyue.aop.annotion;
    
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * Created by liyue on 2016/11/17.
     */
    public class App
    {
        private ApplicationContext applicationContext = new ClassPathXmlApplicationContext("per/liyue/aop/annotion/bean-aop.xml");
    
        @Test
        public void appTest()
        {
            UserDao userDao = applicationContext.getBean("userDao", UserDao.class);
            userDao.save();
        }
    }
    

    2.2配置方式实现AOP

  • 相关阅读:
    mysql压缩版安装
    网站还没加载完成时,显示正在加载的画面
    LESS基础教程
    用CSS编写多种常见的图形
    JavaScript的this
    JavaScript的闭包
    立即执行函数表达式(自执行函数)
    JavaScript的全局变量
    关于async function(){ let res = await } 详解
    mysql数据库的系统操作基本操作
  • 原文地址:https://www.cnblogs.com/bugstar/p/6078138.html
Copyright © 2020-2023  润新知