当前位置: 首页 > article >正文

Spring框架AOP增强,动态代理

为什么需要AOP

AOP全名(Aspect-oriented programming)面向切面编程大法,它有很多兄弟,分别是经常见的面向对象编程,朴素的面向过程编程和神秘的函数式编程等。

AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理。本文就主要讲解AOP的基本术语,最后介绍一下AOP的两种代理方式:

(1)以AspectJ为代表的静态代理。

(2)以Spring AOP为代表的动态代理。

AOP的基本概念

AOP:面向切面编程,不修改源代码的基础上对代理对象的功能进行增强,要指定增强位置配置该位置做的事情

 1.切面(Aspest)

一个切面能够包含同一个类型的不同增强方法.切面由切入点和通知组成,它既包含了横切逻辑的定义,也包括了切入点的定义。 Spring AOP就是负责实施切面的框架,它将切面所定义的横切逻辑织入到切面所指定的连接点中,(使用 @Aspect 注解的类就是切面)。

2.目标对象(Target)

目标对象指将要被增强的对象,即包含主业务逻辑的类对象。或者说是被一个或者多个切面所通知的对象。

3. 连接点(JoinPoint)

程序执行过程中明确的点,连接点就是被拦截到的程序执行点,因为Spring只支持方法类型的连接点,所以在Spring中连接点就是被拦截到的方法。

4.增强处理

Advisor是切面的另外一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将通知包装为更复杂切面的装配器。

5.切入点(PointCut)

切入点是对连接点进行拦截的条件定义。

深入理解AOP增强

1.导入所需的jar包

 2.分层结构

 3.创建一个类,这个类完成核心功能。

(1)创建接口

package com.xue.service;
/*
* 演员接口
* */
public interface Actor {
    //唱
    void sing();
    //跳
    void dance();
    //rap
    void rap();
    //篮球
    void baskball();
}

(1)实现接口

package com.xue.service.Impl;

import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;
import com.xue.service.Actor;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

public class IKUN implements Actor {
    @Override
    public void sing() {
        System.out.println("只因你太美");
    }

    @Override
    public void dance() {
        System.out.println("迎面走来的你");
    }

    @Override
    public void rap() {
        System.out.println("让我如此蠢蠢欲动");
    }

    @Override
    public void baskball() {
        System.out.println("这种感觉我从未有");
    }


}

这个类可以被其他类实例化,并调用实现的方法。

4.创建Loger类,用来做功能的增强。

package com.xue.logger;

public class Logger {
    public void beforePrintLog(){
        System.out.println("前置通知:beforePrintLog执行...");
    }
    public void afterReturningPrintLog(){
        System.out.println("后置通知:afterReturningPrintLog执行...");
    }
    public void afterThrowingPrintLog(){
        System.out.println("异常通知:afterThrowingPrintLog执行...");
    }
    public void afterPrintLog(){
        System.out.println("最终通知:afterPrintLog执行...");
    }
    
}

这个类可以被其他类实例化,并调用其中的方法。通常这些方法会在AOP编程中被调用,用于给程序添加额外的功能或行为。

5.配置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 http://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="logger" class="com.xue.logger.Logger"/>
    <bean id="ikun" class="com.xue.service.Impl.IKUN"/>

    <aop:config>
        <aop:aspect id="xxs" ref="logger">
            <aop:before method="beforePrintLog" pointcut="execution(void com.xue.service.Impl.IKUN.sing())"/>
            <aop:after-returning method="afterReturningPrintLog" pointcut="execution(void com.xue.service.Impl.IKUN.dance())"/>
            <!-- 定义了一个名为afterThrowingPrintLog的方法,使用了切入点表达式execution(* *..CxkServiceImpl.*(..)) -->
            <aop:after-throwing method="afterThrowingPrintLog"  pointcut="execution(void com.xue.service.Impl.IKUN.rap())"/>
            <aop:after method="afterPrintLog"  pointcut="execution(* *..ikun.baskball(..))"/>
         </aop:aspect>
    </aop:config>

</beans>

6.测试方法

package com.xue.servlet;

import com.xue.service.Actor;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test02 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
        Actor actor =context.getBean(Actor.class);
        actor.sing();
        actor.rap();
        actor.dance();
        actor.baskball();
    }
}

深入理解动态代理

在Java开发中如果一个类中的方法在基本功能之外需要进行功能扩充或者功能增强,如:事务控制、权限判断、日志记录等等操作,此时可以使用动态代理机制。

Java的JDK中Proxy类可以实现基于接口的动态代理,实现步骤示例如下:

1.因为Proxy类必须基于接口进行动态代理,所以首先创建接口,定义接口的规范,即功能方法的定义。

package com.xue.service;

public interface BookService {
    //音乐表演
    void musicAct(int money);
    //舞蹈表演
    void danceAct(int money);
    //娱乐表演
    void yueLeAct(int money);
}

2.定义实现接口的子类,实现接口定义的方法,此方法只需要把核心功能实现即可,其他增强的操作可以在代理类中实现。

package com.xue.service.Impl;

import com.xue.service.BookService;

public class BookServiceImpl implements BookService {
    @Override
    public void musicAct(int money) {
        System.out.println("音乐表演");
    }

    @Override
    public void danceAct(int money) {
        System.out.println("舞蹈表演");
    }

    @Override
    public void yueLeAct(int money) {
        System.out.println("娱乐表演");
    }
}


http://www.kler.cn/a/6432.html

相关文章:

  • Hmsc包开展群落数据联合物种分布模型分析通用流程(Pipelines)
  • pm面试题
  • Linux 中 grep、sed、awk 命令
  • LightGBM分类算法在医疗数据挖掘中的深度探索与应用创新(上)
  • Linux中Mysql5.7主从架构(一主多从)配置教程
  • 微服务——技术选型与框架
  • Cursor——ChatGPT的替代品【笔记】
  • linux GlusterFS文件系统 | GFS分布式文件系统群集部署 | 超详细
  • 心理咨询师证书有用吗 有必要考吗
  • Python高阶函数(Higher-order Function)
  • GFS分布式文件系统
  • 【系统可靠性】搭建可靠性系统工程实践
  • 【ArcGIS微课1000例】0067:Nodata数据处理的3种方法案例教程
  • 马上中秋节了,Python带你实现查票以及购票....
  • 文章三:Python网络编程实战:爬虫技术入门与实践
  • 【蓝桥杯冲刺】KMP算法
  • Linux命令·vmstat
  • 【新2023Q2押题JAVA】华为OD机试 - 整理扑克牌
  • gpt4人工智能怎么下载-chatgpt哪里下载
  • 线性表的顺序存储结构具体实现 代码实战 赛博图书馆搭建指南(使用C\C++语言)
  • JavaScript数组对象的浅拷贝与深拷贝(二)实现对象深拷贝的方法(5种)
  • javaScript蓝桥杯----偷梁换柱
  • 什么是语法糖?c语言中有哪些
  • Android布局层级过深为什么会对性能有影响?为什么Compose没有布局嵌套问题?
  • 基于Springboot和MybatisPlus的外卖项目 瑞吉外卖Day4
  • 浅谈ChatGPT取代前端开发工程师