码迷,mamicode.com
首页 > 编程语言 > 详细

Spring框架深入(二)--AOP面向切面

时间:2018-05-20 11:41:37      阅读:172      评论:0      收藏:0      [点我收藏+]

标签:作者   pac   oid   类型   接口   owa   []   join   inf   

一、AOP概述

  1、AOP:面向切面编程,实现在不增加代码的基础上,增加一些新的功能(公共功能);

  2、AOP并不是Spring框架持有的,Spring只是支持AOP编程的框架之一,可以整合第三方框架来实现面向切面编程(如:Aspect);

  3、现实的应用场景:使用面向切面编程,AOP框架已经实现了面向切面的很多内容;

  4、程序员使用AOP要做的事情:

    编写公共功能,切面;

    基于AOP框架的配置,直接把核心业务和切面关联起来;

  5、Spring中实现AOP的方式有三种:

    基于AspectJ注解的方式实现

    基于schema的XML配置

    基于ProxyFactoryBean代理实现

 

二、AOP的简单实现_基于AspectJ注解

  编写步骤如下:

  1、创建一个简单的工程,引入jar包:

  技术分享图片

  2、编写核心业务的接口和实现类

public interface ServiceInterface {
    public void sayHello();

    public void sayBye();
}
/*
 * 核心关注点,核心业务
 * */
@Component("service")
public class ServiceImpl implements ServiceInterface {
    @Override
    public void sayHello() {
        // TODO Auto-generated method stub
        System.out.println("say Hello");
    }
    public void sayBye() {
        System.out.println("say Bye");
    }
}

  3、编写一个切面类:我们就简单的做一个打印输出

/*
 * 公共功能:切面
 * */
@Component
@Aspect
public class AdviceMethod {
    //前置通知
    //将这个方法织入核心业务:
    //@Before,表示在核心业务之前织入;
    //execution,表示织入的位置在哪儿
    @Before("point()")
    public void befor() {
        System.out.println("日志");
    }
}

  4、在核心配置文件中声明这个类为切面

<!-- 启用注解 -->
<context:annotation-config></context:annotation-config>
<!-- 扫描 -->
<context:component-scan base-package="service,advice"></context:component-scan>
<!-- 启用AOP aspectj 的配置 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

  5、最后新建一个测试类

public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    //要使用接口来声明核心业务类
    //service就是一个代理对象
    ServiceInterface service = (ServiceInterface) ac.getBean("service");
    //sayHello代码不需要改变,会自动增加日志的功能
    service.sayHello();
    service.sayBye();
}

    注:这儿必须要用接口来声明核心业务类

  这样,一个简单的AOP案例就搭建完成了;

 

三、AOP详解

  利用一种横切的技术,剖析封装的对象的内部,将影响了多个累的行为封装到了一个可重用的模块中,成为Aspect,切面;

  将应用程序中的商业逻辑与其提供支持的通用服务进行分离;

  1、AOP中的常用术语

    (1)切面:公共功能、交叉功能的描述

    (2)通知:实现切面功能的类

    (3)目标对象:被通知的对象,核心关注点的对象

    (4)代理对象:代理的是目标对象,通过代理目标对象就增加了切面功能

      目标对象+切面功能

      实现切面功能最早使用的是代理对象

    (5)连接点:静态概念,代表通知执行的地方

    (6)切入点:动态概念,运行时执行通知的地方,实现切面功能是,连接点就变为切入点;

    (7)引入:静态概念,将切面与目标对象关联起来

    (8)织入:将切面应用到代理对象,是一个过程

  2、通知类型

    前置通知:核心业务执行前执行

    返回后通知:核心业务返回后执行

    异常通知:核心业务发生异常时执行

    后置通知:核心业务执行后执行

    环绕通知:核心任务执行的时候执行

  代码编写如下:使用注解的方式;

@Before("execution(* service.*.*.*())")
public void befor() {
    System.out.println("前置通知,日志");
}
@After("execution(* service.*.*.*())")
public void after() {
    System.out.println("后置通知,执行完成");
}
@AfterReturning("execution(* service.*.*.*())")
public void afterReturn() {
    System.out.println("返回后通知,得到返回值后");
}    
@AfterThrowing("execution(* service.*.*.*())")
public void throwExp() {
    System.out.println("异常通知,异常执行时");
}    
@Around("execution(* service.*.*.*())")
public Object round(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("环绕前。。。");
    Object o=pjp.proceed();//核心业务的正常执行
    System.out.println("环绕后。。。");
    return o;
}

    执行结果:

    技术分享图片

  3、AspectJ中使用的注解

  (1)、AspectJ是一个面向切面的框架;

  (2)、Spring通过AspectJ实现了一注解的方式定义AOP相关的配置,减少了对于配置文件的依赖

  (3)、AspectJ提供的注解:

    @AspectJ:在类上使用,声明该类为一个切面;

    @Before:在方法上使用,声明该方法的通知类型;

    @After:在方法上使用,声明该方法的通知类型;

    @AfterReturn:在方法上使用,声明该方法的通知类型;

    @AfterThrowing:在方法上使用,声明该方法的通知类型;

    @Around:在方法上使用,声明该方法的通知类型;

    @Pointcut:声明切入点;

@Pointcut("execution(* service.*.*.*())")
public void point() {
}
@Before("point()")
public void befor() {
    System.out.println("前置通知,日志");
}

  4、execution表达式的使用

    AOP配置时,不管是XML配置,注解配置,用于定义pointcut切入点

    execution(* service.*.*.*(..))

    技术分享图片

  5、AOP案例_基于schema

    通过核心配置文件来实现AOP切面类

<!-- AspectJ所提供的基于AOP的配置项 -->
<aop:config>
    <aop:pointcut expression="execution(* service.*.*.*(..))" id="pointCut"/>
    <aop:aspect id="myAspect" ref="adviceMethod_xml">
        <aop:before method="before" pointcut-ref="pointCut"/>
        <aop:after method="after" pointcut-ref="pointCut"/>
        <aop:after-returning method="afterReturn" pointcut-ref="pointCut"/>
        <aop:after-throwing method="throwExp" pointcut-ref="pointCut"/>
        <aop:around method="round" pointcut-ref="pointCut"/>
    </aop:aspect>
</aop:config>

    其实现效果和基于注解一样;

 

PS:因作者能力有限,如有误还请谅解

Spring框架深入(二)--AOP面向切面

标签:作者   pac   oid   类型   接口   owa   []   join   inf   

原文地址:https://www.cnblogs.com/WHL5/p/9062726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!