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

AOP实现之ajc编译器

AOP的另一种实现及原理

A10Application.java

package com.lucifer.itheima.a10;

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

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

        // 不是代理,说明aop的实现不只代理,这种没有用代理来实现,用的是aspect的编译器来进行增强,这个编译器的原理,就是把我们MyService的类改写了,改写后的class加入了前置增强,最终编译的class
        // 类在target->classes->包->MyService.class 把这个文件找到,然后拖到idea中来,idea就可以帮我们反编译,编译好的结果中,在我们的foo()方法中多了MyAspect
        // .aspectOf().before()方法的调用,所以是改写了class来实现增强,目标的类文件都被改写了,那还需要用代理吗,那就不需要了,既然class容器都被改写了,那么跟spring
        // 容器有关系吗,没有关系,我们的MyAspect切面类没有加@Component注解,说明他并不是由spring来管理的,它是由aspect的编译器来读到切面然后做的增强,并不是spring做的增强,
        log.info("service class:{}",service.getClass());
        service.foo();
        context.close();
    }
}

MyAspect.java

package com.lucifer.itheima.a10.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.a10.service.MyService.foo())")
    public void before(){
        log.info("before()");
    }
}

MyService.java

package com.lucifer.itheima.a10.service;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class MyService {

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

pom.xml中添加插件

			<plugin>
				<groupId>org.codehaus.mojo</groupId>
				<artifactId>aspectj-maven-plugin</artifactId>
				<version>1.14.0</version>
				<configuration>
					<comlianceLevel>1.8</comlianceLevel>
					<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>

class文件中,显示的是:

MyService.class

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.lucifer.itheima.a10.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 void foo() {
    	MyAspect.aspectOf().before();
        log.info("foot()");
    }
}

你可能感兴趣的:(spring,学习,笔记)