Spring底层原理学习笔记--第十讲--(aop之agent增强)

AOP实现之agent类加载

AOP的另一种实现及原理

A11Application.java

java 复制代码
package com.lucifer.itheima.a11;

import com.lucifer.itheima.a11.service.MyService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 *  注意几点
 *  1.版本选择了java 8,因为目前的aspectj-maven-plugin 1.40.0 最高只支持到java 16
 *  2.运行时需要在VM option里加入 -jaavaagent:C:/Users/manyh/.m2/repository/org/aspectj/aspectjweaver/1.9.7.jar
 *      把其中C:/Users/manyh/.m2/repository改为自己maven仓库起始地址
 *
 *  在类加载阶段修改了MyService类的字节码
 *
 *  目前为止,讲了三种aop的实现,第一种就是代理实现,第二种就是上讲学到的用aspect编译器,在编译阶段修改字节码,这节课讲的是agent,agent就是在java类加载阶段去改动我们待增强的字节码
 *  但是后面这两种没有流行起来,实际开发过程中开始以代理为主
 */
@SpringBootApplication
@Slf4j
public class A11Application {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(A11Application.class,args);
        MyService service = context.getBean(MyService.class);


        //MyService 并非代理,但foo方法也被增强了,做增强的java agent,在加载类时,修改了class字节码
        log.info("service class:{}",service.getClass());

        //输出结果为
        //before()
//        2023-11-14 10:51:15.898  INFO 18864 --- [           main] c.lucifer.itheima.a11.service.MyService  : foo()
        //before()
//        2023-11-14 10:51:15.898  INFO 18864 --- [           main] c.lucifer.itheima.a11.service.MyService  : bar()
        service.foo();
    }
}

MyService.java

java 复制代码
package com.lucifer.itheima.a11.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class MyService {

    final public void foo(){
        log.info("foo()");
        bar();
    }

    public void bar(){
        log.info("bar()");
    }
}

MyAspect.java

java 复制代码
package com.lucifer.itheima.a11.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect     //注意此切面未被Spring管理
@Slf4j
public class MyAspect {

    @Before("execution(* com.lucifer.itheima.a11.service.MyService.*())")
    public void before(){
        log.info("before()");
    }
}

MyService.class反编译后的代码

java 复制代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.lucifer.itheima.a11.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class MyService {
    private static final Logger log = LoggerFactory.getLogger(MyService.class);

    public MyService() {
    }

    public final void foo() {
    	MyAspect.aspectOf().before();
        log.info("foo()");
        this.bar();
    }

    public void bar() {
    	MyAspect.aspectOf().before();
        log.info("bar()");
    }
}
相关推荐
深圳老胡几秒前
STM32F4 OTA升级:单App与双App方案优缺点对比
笔记·stm32·单片机·代码规范
CV工程师丁Sir2 小时前
ArkWeb 手记 04|DevTools 调试与缓存清理
java·spring·缓存·harmonyos
yi0119 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
Joy T9 小时前
Spring AI 项目中的 pom.xml、application.yml 与 Nacos:从依赖管理到运行配置
spring·nacos·pom.xml·profile·参数配置·application.yml
志尊宝10 小时前
Vue3 零基础每日笔记(073):keep-alive 页面缓存实战——列表页返回不丢状态
vue.js·笔记·缓存·#vue #前端 #前端开发·#javascript·#vue.js
李日华大战鸡红11 小时前
FOC状态空间方程模型推导(学习记录)
python·学习·线性代数
weixin_4481199411 小时前
Datawhale Easy Data × AI:笔记1 已重做,看新的笔记
笔记
要开心吖ZSH12 小时前
MySQL 慢 SQL 排查操作手册-个人笔记版
java·笔记·sql·mysql·慢查询
kkkkkkkkkk_Z13 小时前
新手自学嵌入式 | 学习日记:异常与中断基础、i.MX6ULL裸机开发环境搭建、GPIO模块与点灯原理
学习
咖啡忍者13 小时前
【SAP】程制造生产计划PP-PI(Production Planning for Process Industries)
笔记