AOP源码分析

首先了解下AOP使用
1.创建一个用于拦截的bean

@Component
@Slf4j
public class TestBean {
    private String testStr = "testStr";

    public String getTestStr() {
        return testStr;
    }
    public void setTestStr(String testStr) {
        this.testStr = testStr;
    }
    public void test() {
        log.info("test");
    }
}

2.创建Advisor

@Aspect
@Slf4j
@Component
public class AspectJTest {
    @Pointcut("execution(* *.test(..))")
    public void test(){}

    @Before("test()")
    public void beforeTest() {
        log.info("beforeTest");
    }

    @After("test()")
    public void afterTest() {
        log.info("afterTest");
    }

    @Around("test()")
    public Object aroundTest(ProceedingJoinPoint p) {
        log.info("before1");
        Object o = null;
        try {
            o = p.proceed();
        } catch (Throwable e) {
            e.printStackTrace();
        }
        log.info("after1");
        return o;
    }
}

3.测试
在这里插入图片描述
4.结果
在这里插入图片描述
5.maven依赖

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

如果使用的spring那么需要xml中加入<aop:aspectj-autoproxy/>,配置文件声明后,就会支持注解AOP。
springboot用这个注解@EnableAspectJAutoProxy

在这里插入图片描述
注册了一个AspectJAutoProxyBeanDefinitionParser解析器,解析标签的。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法
来具体看下如何创建自动代理创建器。cls为AnnotationAwareAspectJAutoProxyCreator.class
在这里插入图片描述
2.useClassProxyingIfNecessary方法
在这里插入图片描述
proxy-target-class:使用JDK或CGLIB创建代理对象。如果被代理的目标对象实现了至少一个接口,则使用JDK代理。若没有实现任何接口,则创建一个CGLIB代理。

具体看一下AnnotationAwareAspectJAutoProxyCreator类。
在这里插入图片描述
可以看到他实现了postProcessAfterInitialization方法,继承的是BPP类
在这里插入图片描述
wrapIfNecessary方法
在这里插入图片描述
getAdvicesAndAdvisorsForBean获取增强方法
在这里插入图片描述
findEligibleAdvisors方法,获取出bean所适用的增强器。
在这里插入图片描述
findCandidateAdvisors获取增强器。
在这里插入图片描述
buildAspectJAdvisors方法用于获取注解形式的增强器。
实现步骤

  1. 获取所有的beanName。
  2. 遍历所有的beanName,找到带有AspectJ注解的类。
  3. 提取出这些类的增强器。
  4. 将结果加入缓存当中。

在这里插入图片描述
获取到的增强方法都会放到advisorsCache或aspectFactoryCache中。
最后通过aspectName来从cache中取出,放到统一的List集合中,返回。这样就获取了所有的增强方法。

然我们看下增强器的获取this.advisorFactory.getAdvisors(factory)。getAdvisorMethods主要获取没有声明为pointcut的方法。
在这里插入图片描述
getAdvisorMethods根据切面类来获取增强方法
在这里插入图片描述
getAdvisor根据增强方法构建出增强器。
在这里插入图片描述
InstantiationModelAwarePointcutAdvisorImpl方法,用于根据切点信息生产增强器。在封装过程中只是简单地将信息封装在类的实例中。

再回顾一下获取需要的增强器,先找到所有的增强器,然后再找到该bean适用的增强器。
在这里插入图片描述
findAdvisorsThatCanApply找到bean适用的增强器。
在这里插入图片描述
获取了对应bean的所有增强器后,就可以进行代理的创建了。
再看一下代理创建器中的bpp before干了哪些事情。
在这里插入图片描述
createProxy方法
1.获取当前类中的属性
2.添加代理接口
3.封装Advisor加入到ProxyFactroy中
4.设置要代理的类
5.提供定制函数,子类可以在此函数中进行对ProxyFactory的进一步封装。
6.进行获取代理操作。
在这里插入图片描述
createAopProxy方法创建代理类。
在这里插入图片描述
让我们接下来看看如何获取代理类。JDK、CGLIB

public interface UserService {
    /**
     * 目标方法
     */
    public abstract void add();
}
public class UserServiceImpl implements UserService {
    @Override
    public void add() {
        System.out.println("------add------");
    }
}
public class MyInvocationHandler implements InvocationHandler {
    // 目标对象
    private Object target;

    public MyInvocationHandler(Object target) {
        super();
        this.target = target;
    }
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        System.out.println("---------before--------");
        // 执行目标方法
        Object result = method.invoke(target, objects);
        System.out.println("---------after---------");
        return result;
    }

    /**
     * 获取目标对象的代理对象
     * @return
     */
    public Object getProxy() {
        return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), target.getClass().getInterfaces(), this);
    }
}
public class ProxyTest {
    public static void testProxy() {
        UserService userService = new UserServiceImpl();
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(userService);
        UserService proxy = (UserService) myInvocationHandler.getProxy();
        proxy.add();
    }

    public static void main(String[] args) {
        testProxy();
    }
}

在这里插入图片描述
JdkDynamicAopProxy肯定是实现了InvocationHandler接口,实现了invoke方法。
invoke方法最后会通过拦截器链来依次执行每一个增强器,顺序不固定,然后最后会执行目标方法。

CGLIB看不下去了!!!!我太难了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值