首页 > 其他分享 >Spring 高级 AOP 实现之 agent 增强

Spring 高级 AOP 实现之 agent 增强

时间:2022-09-24 15:45:47浏览次数:40  
标签:Spring AOP boot agent aspectj springframework import org class

一、代码 

package com.itheima.aop;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

    private static final Logger log = LoggerFactory.getLogger(MyAspect.class);

    @Before("execution(* com.itheima.service.MyService.*())")
    public void before() {
        log.debug("before()");
    }
}
package com.itheima.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);

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

    public void bar() {
        log.debug("bar()");
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.itheima</groupId>
    <artifactId>aspectj_02</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>aspectj_02</name>
    <description>aspectj_02</description>
    <properties>
        <java.version>8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
package com.itheima;

import com.itheima.service.MyService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/*
    注意几点
    1. 版本选择了 java 8, 因为目前的 aspectj-maven-plugin 1.14.0 最高只支持到 java 16
    2. 运行时需要在 VM options 里加入 -javaagent:C:/Users/manyh/.m2/repository/org/aspectj/aspectjweaver/1.9.7/aspectjweaver-1.9.7.jar
        把其中 C:/Users/manyh/.m2/repository 改为你自己 maven 仓库起始地址
 */
@SpringBootApplication
public class A10 {

    private static final Logger log = LoggerFactory.getLogger(A10.class);

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

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

//        context.close();

        /*
            学到了什么
            1. aop 的原理并非代理一种, agent 也能, 只要字节码变了, 行为就变了
         */
    }
}

二、测试

发现确实执行了切面类里面的方法,对目标方法增强了

查看编译后的Class文件,发现Class文件并没有被改动

用Arthas反编译,查看发现 在java类加载阶段改动了目标方法的字节码,从而实现对目标方法的增强

 

 

 

 

 

标签:Spring,AOP,boot,agent,aspectj,springframework,import,org,class
From: https://www.cnblogs.com/mangoubiubiu/p/16725758.html

相关文章

  • Spring 高级 AOP 实现之 ajc 编译器
    一、代码packagecom.itheima.aop;importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;importorg.slf4j.Logger;importorg.......
  • SpringMVC之拦截器
    目录HandlerInterceptor定义重要接口及类AbstractHandlerMappingHandlerExecutionChainMappedInterceptorHandlerInterceptor解析与初始化解析初始化拦截器时序原理拦截......
  • Spring事务传播实现原理
    什么是事务传播?假设这样一个场景:方法A上面添加了一个@Transactional注解,在该方法中去调用另一个Service的方法B,但方法B并不需要事务,但是由于A开启了事务,导致B方法的执行也......
  • SpringMVC之映射原理
    目录定位HandlerMethodRequestMappingInfoHandlerMapping提供的getHandlerInternal实现AbstractHandlerMethodMapping提供的getHandlerInternal实现根据请求路径去映射集合......
  • python爬虫随机headers伪装fake_useragent
    python爬虫随机headers伪装fake_useragentfake_useragent库调用方法ua.random可以随机返回一个headers(User-Agent)fromfake_useragentimportUserAgent#下载:pip......
  • 2022-09-22 第二小组 张晟源(SpringMVC)
    SpringMVCSpringMVCSpringMVC是Spring内置的MVC框架,他的MVC模式(Model-View-Controller):解决页面代码和后台代码的分离。SpringMVC原理在没有使用SpringMVC之前我们都......
  • spring security 认证和授权简单流程了解
    1.总结:昨天主要是对WebSecurityConfigurerAdaptor的三个函数的区分以及了解了springsecurity的认证和授权流程;再就是动手使用了下thymeleaf和freeMark的模板以及使用JSON......
  • SpringCloud使用注解+AOP+MQ来实现日志管理模块
    简介无论在什么系统中,日志管理模块都属于十分重要的部分,接下来会通过注解+AOP+MQ的方式实现一个简易的日志管理系统思路注解: 标记需要记录日志的方法AOP: 通过AOP......
  • AOP
    AOP  AOP的入门案例:          AOP的工作流程  SpringAop的本质是:代理模式 AOP的切入点表达式 ......
  • 自定义的配置文件,如何注入到SpringBoot?
    一、简介在实际的项目开发过程中,我们经常需要将某些变量从代码里面抽离出来,放在配置文件里面,以便更加统一、灵活的管理服务配置信息。比如,数据库、eureka、zookeeper、redi......