sping源码debug方法

olivee 2年前 ⋅ 1187 阅读

1 创建maven项目

1.1 pom.xml

<?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>

    <groupId>olivee.study</groupId>
    <artifactId>spring-aop</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <start-class>olivee.study.App</start-class>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
        </dependency>
        
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <dependencies>
                    <dependency>
                        <groupId>org.springframework</groupId>
                        <artifactId>springloaded</artifactId>
                        <version>1.2.6.RELEASE</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

</project>

1.2 编写java类

  • App.java
package olivee.study;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;


@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
@ComponentScan(basePackageClasses = {IWorker.class})
public class App {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(App.class);
        WomanWorker womanWorker = context.getBean("womanWorker",WomanWorker.class);
        womanWorker.work();
        context.close();
    }
}
  • IWorker.java
package olivee.study;

public interface IWorker {
    void work();
}
  • ManWorker.java
package olivee.study;

import org.springframework.stereotype.Component;

@Component
public class ManWorker implements IWorker{
    public ManWorker(){
        System.out.println("ManWorker");
    }
    @Override
    public void work() {
        System.out.println("man worker");
    }
}

  • WomanWorker.java
package olivee.study;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class WomanWorker implements IWorker,InitializingBean {

    @Value("${spring.config.value1}")
    private String value1;
    
    Dog dog;
    public Dog getDog() {
        return dog;
    }
    @Autowired
    public void setDog(Dog dog) {
        System.out.println("set dog value");
        this.dog = dog;
    }
    public WomanWorker(){
        System.out.println("Construct WomanWorker");
    }

    @PostConstruct
    public void doPostConstruct(){
        System.out.println("doPostConstruct");
    }

    @PreDestroy
    public void doPreDestroy(){
        System.out.println("PreDestroy");
    }

    @Override
    public void work() {
        System.out.println("woman worker");
        System.out.println("value1=" + value1);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
}
  • Dog.java
package olivee.study;

import org.springframework.stereotype.Component;

@Component
public class Dog {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

  • WorkerAspectJ.java
package olivee.study;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class WorkerAspectJ {
    
    @Pointcut("execution(* olivee.study.IWorker.work(..))")
    public void pointcutWork(){}

    @Before("pointcutWork()")
    public void beforWork(){
        System.out.println("befor work");
    }

    @After("execution(* olivee.study.IWorker.work(..))")
    public void afterWork(){
        System.out.println("after work");
    }

    @Before(value = "execution(* olivee.study.IWorker.work(..))")
    public void beforWork(JoinPoint joinPoint) {
        System.out.println("befor work2");
    }
 
    @Around(value = "execution(* olivee.study.IWorker.work(..))")
    public void around(ProceedingJoinPoint pjp) throws  Throwable{
        System.out.println("around work ");
        pjp.proceed();
        System.out.println("around work 2");
    }

}

2. 启动debug

2.1 调试ioc代码

  • 在WomanWorker.java或ManWorker.java的构造方法内加断点,即可跟踪bean的实例化过程
  • 在WomanWorker的setDog方法加断点,即和调试bean的设置属性过程
  • 在AbstractAutowireCapableBeanFactory的applyMergedBeanDefinitionPostProcessors方法加断点,可以调试ioc的合并BeanDefinition过程

2.2 调试AOP代码

  • 在DefaultAopProxyFactory的createAopProxy方法加断点,即和调试创建AOP代理bean的主要过程
  • 在WorkerAspectJ类的方法中加断点,即喝调试AOP代理执行代理的过程

如下图所示,debug aop创建代理的代码:

image-20220211174132601.png