首页 > 其他分享 >Spring 高级 AOP 实现之 ajc 编译器

Spring 高级 AOP 实现之 ajc 编译器

时间:2022-09-24 15:24:48浏览次数:52  
标签:Spring AOP boot springframework class 编译器 import org aspectj

一、代码

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.foo())")
    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);

    public static void foo() {
        log.debug("foo()");
    }
}
<?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_01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>aspectj_01</name>
    <description>aspectj_01</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>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.14.0</version>
                <configuration>
                    <complianceLevel>1.8</complianceLevel>
                    <source>8</source>
                    <target>8</target>
                    <showWeaveInfo>true</showWeaveInfo>
                    <verbose>true</verbose>
                    <Xlint>ignore</Xlint>
                    <encoding>UTF-8</encoding>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <!-- use this goal to weave all your main classes -->
                            <goal>compile</goal>
                            <!-- use this goal to weave all your test classes -->
                            <goal>test-compile</goal>
                        </goals>
                    </execution>
                </executions>
            </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. 一定要用 maven 的 compile 来编译, idea 不会调用 ajc 编译器
 */
@SpringBootApplication
public class A09 {

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

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

        log.debug("service class: {}", service.getClass());
        service.foo();

        context.close();

//        new MyService().foo();

        /*
            学到了什么
            1. aop 的原理并非代理一种, 编译器也能玩出花样
         */
    }
}

二、测试

发现确实执行了切面类里面的方法,现了对目标方法的增强处理,当时打印目标方法对象时,并不是代理类,说明此时AOP并不是用代理来实现的,是用的Aspect的编译器进行增强。

查看源码,发现是改写了Class文件实现对目标方法的增强

既然Class被改写了,说明该类没有被Spring容器管理

测试 自己直接创建对象,发现目标方法还是被增强了

收获

标签:Spring,AOP,boot,springframework,class,编译器,import,org,aspectj
From: https://www.cnblogs.com/mangoubiubiu/p/16725689.html

相关文章

  • SpringMVC之拦截器
    目录HandlerInterceptor定义重要接口及类AbstractHandlerMappingHandlerExecutionChainMappedInterceptorHandlerInterceptor解析与初始化解析初始化拦截器时序原理拦截......
  • Spring事务传播实现原理
    什么是事务传播?假设这样一个场景:方法A上面添加了一个@Transactional注解,在该方法中去调用另一个Service的方法B,但方法B并不需要事务,但是由于A开启了事务,导致B方法的执行也......
  • SpringMVC之映射原理
    目录定位HandlerMethodRequestMappingInfoHandlerMapping提供的getHandlerInternal实现AbstractHandlerMethodMapping提供的getHandlerInternal实现根据请求路径去映射集合......
  • 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......
  • Spring创建对象的方式
    ​ /**作者:呆萌老师*☑csdn认证讲师*☑51cto高级讲师*☑腾讯课堂认证讲师*☑网易云课堂认证讲师*☑华为开发者学堂认证讲师*☑爱奇艺千人名师计划成员*在这里......
  • 【Nacos】最新版本 Spring Cloud Alibaba nacos 负载均衡调用异常 没有找到对应主机
    问题原因:最新版本的Nacos中没有依赖任何负载均衡的包,解决办法:需要手动引入Ribbon或者LoadBalancer,这里建议引入LoadBalancer,因为Ribbon已经处于维护状态......