资讯专栏INFORMATION COLUMN

Spring还可以这么学--AOP

chinafgj / 3295人阅读

摘要:还可以这么学上一篇文章还可以这么学控制反转依赖注入理解什么是,即面向切面编程,可以说是,面向对象编程的补充和完善。

Spring还可以这么学--AOP

上一篇文章Spring还可以这么学--IoC(控制反转) / DI(依赖注入)理解

1. 什么是AOP?

AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。

2. AOP的作用?

利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

首先我们来看没有AOP时,如果我们要做日志处理,就得在每个方法中添加

但大多数日志处理代码都是相同的,所以我们将日志处理抽离成一个新的方法,但是尽管这样,我们还得手动插入这些方法。

但这样代码的耦合度很高,当我们要更改这个功能时,就得一个个更改

使用AOP后

为了在指定位置执行这些横向的功能,需要知道指定的是什么地方

例如上图,方法级别的aop实现,在一个程序执行链条中,把method2称为切点,也就是说在method2执行时会执行横切的功能,那么是在method2之前还是之后呢,又是执行什么呢?这些都由advice(通知)来指定。
Spring 方面可以使用下面提到的五种通知工作:

3. AOP的核心概念

横切关注点:对哪些方法进行拦截,拦截后怎么处理,这些关注点称之为横切关注点

切面(aspect):类是对物体特征的抽象,切面就是对横切关注点的抽象

连接点(joinpoint):被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器

切入点(pointcut):对连接点进行拦截的定义

通知(advice):所谓通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类

目标对象:代理的目标对象

织入(weave):将切面应用到目标对象并导致代理对象创建的过程

引入(introduction):在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段

4. 实现方式 Spring AOP的XML实现方式

Employee.java文件

package com.wangc;

public class Employee {
    private String name;
    private int age;
    public String getName() {
        System.out.println("name = "+name);
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        System.out.println("age = "+age);
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public void printThrowException() {
        System.out.println("发生异常");
        throw new IllegalArgumentException();
    }
}

Logging.java文件

package com.wangc;

public class Logging {
    //在一个方法执行之前,执行通知。
    public void beforeAdvice(){
        System.out.println("执行employee的方法之前执行.");
    }
    //在一个方法执行之后,不考虑其结果,执行通知。
    public void afterAdvice(){
        System.out.println("执行employee的方法之后执行.");
    }
    //在一个方法执行之后,只有在方法成功完成时,才能执行通知。
    public void afterReturningAdvice(Object retVal){
        System.out.println("返回:" + retVal.toString() );
    }
    //在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
    public void AfterThrowingAdvice(IllegalArgumentException ex){
        System.out.println("抛出了一个异常: " + ex.toString());   
    }  
}

Beans.xml文件




   
      
      
         
         
         
         
         
         
         
         
         
         
      
   

   
      
            
   

    

MyApp.java文件

package com.wangc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyApp {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        Employee employee = (Employee) context.getBean("employee");
        employee.getName();
        employee.getAge();
        employee.printThrowException();
    }
}

执行结果:

执行employee的方法之前执行.
name = zhangsan
执行employee的方法之后执行.
返回:zhangsan
执行employee的方法之前执行.
age = 28
执行employee的方法之后执行.
返回:28
执行employee的方法之前执行.
发生异常
执行employee的方法之后执行.
抛出了一个异常: java.lang.IllegalArgumentException
Exception in thread "main" java.lang.IllegalArgumentException
......

注意:上面的例子只有一个横切关注点,如果有多个横切关注点,可以使用aspect里的order属性来控制横切关注点的顺序。

......
   
      
         
         
      
      
         
         
      
   
   ......
Spring AOP 的 @AspectJ实现方式

这里只需要在上面的基础上修改以下两个文件就可实现,修改后的文件如下:
Beans.xml文件




    
    

    
       
             
    

     

Logging.java文件

package com.wangc;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class Logging {
    @Pointcut("execution(* com.wangc.*.*(..))")
    private void all() {
    }
    //在一个方法执行之前,执行通知。
    @Before("all()")
    public void beforeAdvice(){
        System.out.println("执行employee的方法之前执行.");
    }
    //在一个方法执行之后,不考虑其结果,执行通知。
    @After("all()")
    public void afterAdvice(){
        System.out.println("执行employee的方法之后执行.");
    }
    //在一个方法执行之后,只有在方法成功完成时,才能执行通知。
    @AfterReturning(pointcut = "all()", returning="retVal")
    public void afterReturningAdvice(Object retVal){
        System.out.println("返回:" + retVal.toString() );
    }
    //在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
    @AfterThrowing(pointcut = "all()", throwing="ex")
    public void AfterThrowingAdvice(IllegalArgumentException ex){
        System.out.println("抛出了一个异常: " + ex.toString());   
    }  
}

这里做个简单的说明: 用@Aspect的注解来标识切面,注意不要把它漏了,否则Spring创建代理的时候会找不到它,@Pointcut注解指定了切点,@Before、@After、@AfterReturning和@AfterThrowing指定了运行时的通知。

运行结果:

执行employee的方法之前执行.
name = zhangsan
执行employee的方法之后执行.
返回:zhangsan
执行employee的方法之前执行.
age = 28
执行employee的方法之后执行.
返回:28
执行employee的方法之前执行.
发生异常
执行employee的方法之后执行.
抛出了一个异常: java.lang.IllegalArgumentException
Exception in thread "main" java.lang.IllegalArgumentException
......

上一篇文章Spring还可以这么学--IoC(控制反转) / DI(依赖注入)理解

QQ学习交流群:713479727
微信学习交流群:微信群加入方式【公众号下方菜单栏-->学习资源-->微信群】
微信公众号:EverydayCoding 或扫描下方二维码
欢迎大家加入。。。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/69322.html

相关文章

  • Spring AOP就是这么简单啦

    摘要:是一种特殊的增强切面切面由切点和增强通知组成,它既包括了横切逻辑的定义也包括了连接点的定义。实际上,一个的实现被拆分到多个类中在中声明切面我们知道注解很方便,但是,要想使用注解的方式使用就必须要有源码因为我们要 前言 只有光头才能变强 上一篇已经讲解了Spring IOC知识点一网打尽!,这篇主要是讲解Spring的AOP模块~ 之前我已经写过一篇关于AOP的文章了,那篇把比较重要的知...

    Jacendfeng 评论0 收藏0
  • Aop?看这篇文章就够了!!!

    摘要:又是什么其实就是一种实现动态代理的技术,利用了开源包,先将代理对象类的文件加载进来,之后通过修改其字节码并且生成子类。 在实际研发中,Spring是我们经常会使用的框架,毕竟它们太火了,也因此Spring相关的知识点也是面试必问点,今天我们就大话Aop。特地在周末推文,因为该篇文章阅读起来还是比较轻松诙谐的,当然了,更主要的是周末的我也在充电学习,希望有追求的朋友们也尽量不要放过周末时...

    boredream 评论0 收藏0
  • SpringBoot自动配置原理

    摘要:开启自动配置功能后文详解这个注解,学过的同学应该对它不会陌生,就是扫描注解,默认是扫描当前类下的。简单来说,这个注解可以帮助我们自动载入应用程序所需要的所有默认配置。简单理解这二者扫描的对象是不一样的。 前言 只有光头才能变强。 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面Spring的文章(以学习...

    Rainie 评论0 收藏0
  • Java编程需要注意的地方

    摘要:学编程真的不是一件容易的事不管你多喜欢或是多会编程,在学习和解决问题上总会碰到障碍。熟练掌握核心内容,特别是和多线程初步具备面向对象设计和编程的能力掌握基本的优化策略。   学Java编程真的不是一件容易的事,不管你多喜欢或是多会Java编程,在学习和解决问题上总会碰到障碍。工作的时间越久就越能明白这个道理。不过这倒是一个让人进步的机会,因为你要一直不断的学习才能很好的解决你面前的难题...

    leanxi 评论0 收藏0
  • SpringBoot就是这么简单

    摘要:热加载代表的是我们不需要重启服务器,就能够类检测得到,重新生成类的字节码文件无论是热部署或者是热加载都是基于类加载器来完成的。验证阶段字节码文件不会对造成危害准备阶段是会赋初始值,并不是程序中的值。 一、SpringBoot入门 今天在慕课网中看见了Spring Boot这么一个教程,这个Spring Boot作为JavaWeb的学习者肯定至少会听过,但我是不知道他是什么玩意。 只是大...

    whinc 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<