文档章节

spring-101-springAOP

haoran_10
 haoran_10
发布于 2016/07/15 16:44
字数 1551
阅读 37
收藏 1

阿里云携手百名商业领袖、技术大咖,带您一探行进中的数字新基建!>>>

前言:

在很多场景下有一个共同的业务模块。比如用户在网站购物时,加入商品到购物车,下单,支付,等等,但是所有的业务都需要打日志,但是每个业务重写一遍日志又比较麻烦。此时springAOP可以适用这样的情况。

AOP(Aspect Oriented Programming),即面向切面编程(也叫面向方面编程,面向方法编程)。其主要作用是,在不修改源代码的情况下给某个或者一组操作添加额外的功能。像日志记录,事务处理,权限控制等功能,都可以用AOP来“优雅”地实现,使这些额外功能和真正的业务逻辑分离开来,软件的结构将更加清晰。

springAOP概念较多,但是最为关键的有2个:

  • Advice

        通知,多个业务模块都用到一个共同的功能,那么这个共同的功能,比如打日志,这个就是通知。
  • Pointcut

        切入点,多个业务模块都用到一个共同的功能,那么这个多个业务模块,比如加入商品到购物车,这个就是切入点。

spring为了方便,对这两个进行了组合

  • Advisor

        这个其实是Advice和Pointcut的组合,Advice和Pointcut组成的独立的单元。
    也就是说,多个业务模块都用到一个共同的功能,那么这个整体就叫Advisor

就依用户网站购物,加入商品到购物车,下单,支付都用到了加入日志为例子做一个DEMO。

1.用户多业务场景

用户在网站购物三个业务模块,加入商品到购物车,下单,支付代码,如下,代码清单1:

package wang.conge.springdemo.aop.service;

import org.springframework.stereotype.Component;

import wang.conge.springdemo.aop.annotation.AopLogAnnotation;

@Component
public class UserService {
    
    @AopLogAnnotation
    public void addCar() {
        System.out.println("加入购物车");
    }
    
    @AopLogAnnotation
    public void createOrder() {
        System.out.println("下单");
    }
    
    @AopLogAnnotation
    public void pay() {
        System.out.println("付款");
    }
}

代码清单1 用到了注解作为切入点的最小单元,先列出来,下面说明,代码清单2:

package wang.conge.springdemo.aop.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AopLogAnnotation {
    String value() default "";
}

2.共同业务模块

用户在网站购物三个业务模块,加入商品到购物车,下单,支付代码,但是都用到了加入日志,如下,代码清单3:

package wang.conge.springdemo.aop.service;

import java.lang.reflect.Method;
import java.util.Optional;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.stereotype.Component;

import wang.conge.springdemo.aop.annotation.AopLogAnnotation;

@Component
public class CommonLogAdvisor extends AbstractPointcutAdvisor{
    private static final long serialVersionUID = 1L;
    
    @Override
    public Pointcut getPointcut() {
        return new StaticMethodMatcherPointcut() {
            
            @Override
            public boolean matches(Method method, Class<?> targetClass) {
                //TODO matches targetClass 
                //if(targetClass matches AopTargetClass) return true;
                
                //TODO matches method 
                //if(method matches AopMethod) return true;
                
                if(method.isAnnotationPresent(AopLogAnnotation.class)) {
                    return true;
                }
                
                return false;
            }
            
        };
    }

    @Override
    public Advice getAdvice() {
        return new MethodInterceptor() {
            @Override
            public Object invoke(MethodInvocation invocation) throws Throwable {
                Object ret = null;
                try {
                    //TODO before
                    System.out.println("=====SpringAopAdvisor-调用前before逻辑===");
                    
                    ret = invocation.proceed();
                    
                    //TODO after
                    System.out.println("=====SpringAopAdvisor-调用后after逻辑===");
                    
                    return ret;
                } catch (Exception e) {
                    //TODO throw
                    System.out.println("=====SpringAopAdvisor-调用异常throw逻辑===");
                    return Optional.empty();
                } finally {
                    //TODO finally
                    System.out.println("=====SpringAopAdvisor-调用最终结束逻辑===");
                }
            }
        };
    }
    
}

下面对代码说明,为整个DEMO中核心代码:

  • public Advice getAdvice() ;该方法就是返回共同的业务所做的事情,在业务调用时就会在合适的逻辑之前,或之后,或发生异常,去完成相应的共同逻辑处理。
  • public Pointcut getPointcut() ; 该方法返回拦截业务的规则,事实上,加入商品到购物车,下单,支付并不是切入点,而加入商品到购物车,下单,支付这几个业务怎样在哪里加入共同日志的方式,或者规则,才叫切入点。方法里利用注解的方式,如果方法上注解了AopLogAnnotation,就会拦截,否则不拦截。也可以进进一步从类的Class做拦截的规则,这个看具体业务拦截的方式了。

3.配置代码

剩下的代码则是对上述代码进行组织运行了。
配置代码,启用EnableAspectJAutoProxy支持。代码清单4:

package wang.conge.springdemo.aop.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
@ComponentScan("wang.conge.springdemo.aop.service")
public class AppConfig {
    
}

运行主代码,代码清单5:

package wang.conge.springdemo.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import wang.conge.springdemo.aop.config.AppConfig;
import wang.conge.springdemo.aop.service.UserService;

public class AppStart {

    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
        
        UserService myService = applicationContext.getBean(UserService.class);
        myService.addCar();
        
        myService.createOrder();
    }

}

OK,整个DEMO就结束了,紧紧抓住AOP的主题思想:

  • 多个业务有共同功能,多个业务切入点,也就是被拦截的地方,或者拦截这些多个业务的规则
  • 多个业务共同的功能,也就是该共同功能所做的事情。

上述代码是以springAOP做实例,事实上spring也支持aspectj ,但是运行的方式还是根据代理的形式。
而spring实现AOP的技术,主要分为两大类:

一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;
二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。


如果要是原生的aspectj 还是比较复杂,牵扯到织入的细节。aspectj是aop的Java实现方案。下面是几点关于aspectj的描述:

  • AspectJ是一个代码生成工具(CodeGenerator),其中AspectJ语法就是用来定义代码生成规则的语法。基于自己的语法编译工具,编译的结果是Java Class文件,运行的时候classpath需要包含AspectJ的一个jar文件(Runtime lib),支持编译时织入切面,即所谓的CTW机制,可以通过一个Ant或Maven任务来完成这个操作。
  • AspectJ有自己的类装载器,支持在类装载时织入切面,即所谓的LTW机制。使用AspectJ LTW有两个主要步骤,第一,通过JVM的-javaagent参数设置LTW的织入器类包,以代理JVM默认的类加载器;第二,LTW织入器需要一个 aop.xml文件,在该文件中指定切面类和需要进行切面织入的目标类
  • AspectJ同样也支持运行时织入,运行时织入是基于动态代理的机制。(默认机制)

附录1,AOP详细概念:

附录2,spring aop官方网站介绍资料:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html

© 著作权归作者所有

haoran_10
粉丝 27
博文 89
码字总数 82446
作品 0
杭州
程序员
私信 提问
加载中

评论(0)

蘑菇街Java大牛纯手写肛出的(Spring AOP/IOC思维导图源码笔记)

Spring AOP/IOC思维脑图 需要获取完整高清版Spring AOP/IOC思维脑图与源码笔记的老铁请转发+关注,然后加我VX【tkzl6666】获得免费领取方式! AOP原理 AOP术语 Spring对AOP的支持 知识点 需要...

Java技术箭
04/17
0
0
Spring AOP之同一个对象方法内部自调用导致事务失效问题

对于像我这种喜欢滥用AOP的程序员,遇到坑也是习惯了,不仅仅是事务,其实只要脱离了Spring容器管理的所有对象,对于SpringAOP的注解都会失效,因为他们不是Spring容器的代理类,SpringAOP,就切入不...

xiaomin0322
2019/05/20
812
0
赶紧收藏!Java大牛熬夜一周肝出的《Spring AOP/IOC源码笔记》

Spring AOP/IOC源码笔记脑图 AOP原理 AOP术语 Spring对AOP的支持 知识点 高清完整版Spring AOP/IOC源码笔记脑图请转发+关注,然后私信回复关键字 “笔记” 获得免费领取方式! IOC和DI的概念...

Java技术剑
05/21
0
0
完整剖析SpringAOP的自调用

摘要 spring全家桶帮助java web开发者节省了很多开发量,提升了效率。但是因为屏蔽了很多细节,导致很多开发者只知其然,不知其所以然,本文就是分析下使用spring的一些注解,不能够自调用的...

osc_cw97bsoa
04/16
7
0
SPRING技术内幕:深入解析SPRING架构与设计原理(附赠电子书)

前言: 今天给大家分享的是一本关于spring的电子书,由于篇幅限制本文给大家大致的介绍一下这本书,如若需要电子书关注我的供种浩 Java周某人。 本书主要内容分为三个部分,分别阐述了Spring的...

java周某人
04/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

史上最全的“文件或目录损坏且无法读取”的解决办法大集合

问题描述: G盘打不开文件或目录损坏且无法读取,是因为这个I盘的文件系统内部结构损坏导致的。史上最全的“文件或目录损坏且无法读取”的解决办法大集合具体的恢复方法看正文 工具/软件:极...

计算无敌
今天
9
0
2048游戏的最佳算法是什么? - What is the optimal algorithm for the game 2048?

问题: I have recently stumbled upon the game 2048 . 我最近偶然发现了2048游戏。 You merge similar tiles by moving them in any of the four directions to make "bigger" tiles. 您可......

javail
今天
9
0
Spring Cloud Ribbon 客户端负载均衡

Ribbon客户端组件提供一系列完善的配置选项,比如连接超时、重试、重试算法等,内置可插拔、可定制的负载均衡组件。下面是用到的一些负载均衡策略: 简单轮询负载均衡 加权轮询负载均衡 区域...

泥瓦匠BYSocket
今天
7
0
为什么在Python 3中“范围(1000000000000000(1000000000000001))”这么快?

问题: It is my understanding that the range() function, which is actually an object type in Python 3 , generates its contents on the fly, similar to a generator. 据我了解, ra......

技术盛宴
今天
9
0
OSChina 周四乱弹 —— 卖全家桶!

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @巴拉迪维 :陈慧娴的单曲《与泪抱拥》 陈慧娴的嗓音加上向雪怀的词,这样的经典组合真不多。#今日歌曲推荐# 《与泪抱拥》- 陈慧娴 手机党少年...

小小编辑
今天
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部