AOP及实现方式

作者:神秘网友 发布时间:2021-02-28 11:20:05

AOP及实现方式

AOP及实现方式

一、AOP简介

1.1 什么是AOP

AOP(Aspect Oriented Programming)意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

1.2 Aop在Spring中的作用

提供声明式事务;允许用户自定义切面

  • 横切关注点:跨越应用程序多个模块的方法或功能。即是,与我们业务逻辑无关的,但是我们需要关注的部分,就是横切关注点。如日志 , 安全 , 缓存 , 事务等等 ....

  • 切面(ASPECT):横切关注点 被模块化 的特殊对象。即,它是一个类。

  • 通知(Advice):切面必须要完成的工作。即,它是类中的一个方法。

  • 目标(Target):被通知对象。

  • 代理(Proxy):向目标对象应用通知之后创建的对象。

  • 切入点(PointCut):切面通知 执行的 “地点”的定义。

  • 连接点(JointPoint):与切入点匹配的执行点。

SpringAOP中,通过Advice定义横切逻辑,Spring中支持5种类型的Advice:

即AOP在不改变原有代码的情况下,去增加新的功能。

1.3 使用Spring实现Aop

使用AOP织入,需要导入一个依赖包。

dependency
    groupIdorg.aspectj/groupId
    artifactIdaspectjweaver/artifactId
    version1.9.4/version
/dependency

第一种方式:

通过Spring API来实现,首先编写业务接口和实现类

public interface UserService {
    void add();
    void delete();
    void update();
    void select();
}
public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加一个用户");
    }
?
    @Override
    public void delete() {
        System.out.println("删除一个用户");
    }
?
    @Override
    public void update() {
        System.out.println("更新一个用户");
    }
?
    @Override
    public void select() {
        System.out.println("查找一个用户");
    }
}

然后编写增强类,一个前置增强,一个后置增强

public class Log implements MethodBeforeAdvice {
?
    //method:要执行的目标的方法
    //args:要调用的方法的参数
    //target:目标对象
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"的"+method.getName()+"方法被执行了");
    }
}
public class AfterLog implements AfterReturningAdvice {
//    returnValue 返回值
//    method 被调用的方法
//    args 被调用的方法的对象的参数
//    target 被调用的目标对象
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了"+target.getClass().getName()+"的"+method.getName()+"方法,"+"返回值:"+returnValue);
    }
}

最后去spring的文件中注册,实现aop切入实现。

xml version="1.0" encoding="UTF-8"
beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
?
!--    注册bean--
    bean id="userService" class="com.aishimin.service.UserServiceImpl"/
    bean id="log" class="com.aishimin.log.Log"/
    bean id="afterlog" class="com.aishimin.log.AfterLog"/
?
!--    AOP配置--
    aop:config
!--        切入点expression:表达式匹配要执行的方法--
        aop:pointcut id="pointcut" expression="execution(* com.aishimin.service.UserServiceImpl.*(..))"/
!--        环绕执行;advice-ref执行方法,pointcut-ref切入点--
        aop:advisor advice-ref="log" pointcut-ref="pointcut"/
        aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/
    /aop:config
?
/beans

测试:


第二种方式:

自定义类来实现Aop

目标业务类依旧是userServiceImpl

  1. 写一个自己的切入类

    public class DiyPointCut {
        public void before(){
            System.out.println("------方法执行前-------");
        }
        public void after(){
            System.out.println("------方法执行后-------");
        }
    }

    在spring中进行配置:

    !--    注册bean--
        bean id="userService" class="com.aishimin.service.UserServiceImpl"/
        bean id="log" class="com.aishimin.log.Log"/
        bean id="afterlog" class="com.aishimin.log.AfterLog"/
            
    !--    第二种方式自定义实现--
    !--    注册bean--
        bean id="diy" class="com.aishimin.diy.DiyPointCut"/
    !--    aop的配置--
        aop:config
    !--        第二种方式:使用AOP标签实现--
            aop:aspect ref="diy"
                aop:pointcut id="diyPointCut" expression="execution(* com.aishimin.service.UserServiceImpl.*(..))"/
                aop:before method="before" pointcut-ref="diyPointCut"/
                aop:after method="after" pointcut-ref="diyPointCut"/
            /aop:aspect
        /aop:config

第三种方式实现:

使用注解实现

  1. 编写一个注解实现的增强类

    @Aspect
    public class AnnotationPointCut {
    ?
        @Before("execution(* com.aishimin.service.UserServiceImpl.*(..))")
        public void before(){
            System.out.println("方法执行前");
        }
    ?
        @After("execution(* com.aishimin.service.UserServiceImpl.*(..))")
        public void after(){
            System.out.println("方法执行后");
        }
    ?
        public void around(ProceedingJoinPoint pj) throws Throwable{
            System.out.println("环绕前");
            System.out.println("签名:"+pj.getSignature());
            Object proceed = pj.proceed();
            System.out.println("环绕后");
            System.out.println(proceed);
        }
    }
  2. 在spring配置文件中,注册bean,并增加支持注解的支持

    !--    注册bean--
        bean id="userService" class="com.aishimin.service.UserServiceImpl"/
        bean id="log" class="com.aishimin.log.Log"/
        bean id="afterlog" class="com.aishimin.log.AfterLog"/
    ?
    !--    第三种方式:注解实现--
        bean id="annotationPointcut" class="com.aishimin.diy.AnnotationPointCut"/
        aop:aspectj-autoproxy/

    aop:aspectj-autoproxy/说明:

    通过aop命名空间的注解支持声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被aop:aspectj-autoproxy/注解支持隐藏起来了。

    aop:aspectj-autoproxy /有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为aop:aspectj-autoproxy poxy-target-class="true"/时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。

AOP及实现方式 相关文章

  1. 线性表的顺序表示和实现

    结构体: struct Sqlist { ElemType* elem; int length; };//定义顺序表类型 函数方法 Status InitList(Sqlist L); //初始化 void Destory(Sqlist L);//销毁已存在的线性表 void ClearList(Sqlist L);//清空 int GetLength(Sqlist L); int IsEmpty(Sqlist L)

  2. Go语言实现布谷鸟过滤器

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com/archives/453 介绍 在我们工作中,如果遇到如网页 URL 去重、垃圾邮件识别、大集合中重复元素的判断一般想到的是将集合中所有元素保存起来,然后通过比较确定。如果通过性能最

  3. 基于角色访问控制RBAC权限模型的动态资源访问权限管理实现

    RBAC权限模型(Role-Based Access Control) 前面主要介绍了元数据管理和业务数据的处理,通常一个系统都会有多个用户,不同用户具有不同的权限,本文主要介绍基于RBAC动态权限管理在crudapi中的实现。 概要 RBAC简介 RBAC权限模型(Role-Based Access Contr

  4. 【QT】简易计算器实现

    主要为了配合学习QT,还有一些bug,先不深究 #include "calc.h"#include "ui_calc.h"calc::calc(QWidget *parent) : QMainWindow(parent), ui(new Ui::calc){ ui-setupUi(this); QFont font=this-font(); font.setPixelSize(40); this-setFont(font); window

  5. 线性表的链式表示和实现

    结构体 struct ElemType{ char num[8];//学号 char name[8];//姓名 int score;//分数 };//数据域结构 typedef struct LNode { ElemType data;//数据域 struct LNode* next;//指向下一个的指针 }LNode,*LinkList;//单链表 函数方法 Status InitList_L(LinkLis

  6. go语言设计与实现-数据结构-阅读笔记

    数组 Go 语言中数组在初始化之后大小就无法改变,存储元素类型相同、但是大小不同的数组类型在 Go 语言看来也是完全不同的,只有两个条件都相同才是同一个类型。 func NewArray(elem *Type, bound int64) *Type { if bound 0 { Fatalf("NewArray: invalid bo

  7. SpringAOP理解-代理对象创建(七)

    SpringAOP的核心首先是创建代理对象存入SpringIoC容器中,然后就是调用的时候使用责任链模式进行调用。首先研究SpringAOP创建代理对象的机制。 在Spring的AOP实现中,使用的核心技术是代理技术,而这种动态代理实际上是JDK的一个特性(1.3)。基于JDK动态代理

  8. 单例模式的无锁实现

    在开发过程中经常会遇到单例模式,该模式是工作中最常见的设计模式,简单易用是它的特点。单例一般是通过刚开始就申请内存或者用时申请内存的方式实现,用时动态申请内存的话需要加锁,现在主流的也是双重检测加锁的方式。但是今天要讲的是无锁的方式来完成

  9. css文字在底部怎么写

    css文字在底部的实现方法:首先新建一个html文件,并使用div标签创建一个模块;然后设置div的class属性为con;接着分别在css标签内创建div和p元素的样式;最后设置其位置属性为绝对定位即可。 本教程操作环境:windows7系统、HTML5CSS3版、Dell G3电脑。 新

  10. spring学习(九、使用java方式配置spring)

    九、使用java的方式配置Spring 我们现在完全不使用Spring的xml配置,全权交给java来做 javaConfig是Srping的一个子项目,在Srping4之后,他成为了一个核心功能! 下面是具体测试: 实体类: public class User { private String name; @Override public Stri

每天更新java,php,javaScript,go,python,nodejs,vue,android,mysql等相关技术教程,教程由网友分享而来,欢迎大家分享IT技术教程到本站,帮助自己同时也帮助他人!

Copyright 2020, All Rights Reserved. Powered by 跳墙网(www.tqwba.com)|网站地图|关键词