Spring Boot 中如何使用 Aspect 切面编程

Spring Boot 中如何使用 Aspect 切面编程

(1) . 导入AOP依赖

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

(2) . 创建切面类 设置切入关注点

<!-- 创建切面类 当前类需要 添加 @Aspect 注解 -->
@Aspect
public class AspectDemo {

    @Pointcut("execution (* com.example.init.bean.Car.* (..))")
    public void pointcut () {}

    @Before("pointcut ()")
    public void before (JoinPoint joinPoint) {
        System.out.println(joinPoint.getSignature().getName());
        System.out.println("目标方法执行之前:" );
    }

    @After("pointcut ()")
    public void after (JoinPoint joinPoint) {
        System.out.println(joinPoint.getSignature().getName());
        System.out.println("目标方法执行之后:");
    }

    @AfterReturning(value = "pointcut ()" ,returning = "count")
    public void afterReturning (JoinPoint joinPoint ,int count) {
        System.out.println(joinPoint.getSignature().getName() + "执行的结果是:[" + count + "]");
    }

    @AfterThrowing(value = "pointcut ()" ,throwing = "error")
    public void afterThrowing (JoinPoint joinPoint ,Exception error) {
        System.out.println(joinPoint.getSignature().getName() + "执行产生异常:" + error.getLocalizedMessage());
        error.printStackTrace();
    }
    
}

(3). 给当前项目启用 Aspect 代理

<!-- @EnableAspectJAutoProxy 注解可以添加在spring boot 启动类上 也可以添加配置类上 当前是添加在启动类上 -->
@EnableAspectJAutoProxy
@Configuration
@Import(AspectDemo.class)
public class AspectConfig  {
}

@EnableAspectJAutoProxy 的作用

  1. 查看@EnableAspectJAutoProxy 注解源码
<!-- 查看源码可以发现 该注解为spring 容器添加了一个 AspectJAutoProxyRegistrar.class 类型的 bean ,
下面需要对这个类做了哪些事情进行追踪. -->

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

  1. 查看 AspectJAutoProxyRegistrar.class 类的源码
<!-- ImportBeanDefinitionRegistrar 该接口具有向容器内注册bean 的功能 -->

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * Register, escalate, and configure the AspectJ auto proxy creator based on the value
	 * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
	 * {@code @Configuration} class.
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

<!-- 第一步具体调用见下方 -->
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
			AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
		}
		if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
			AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
		}
	}

}

第一步

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
//  调用了下面的方法
	return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}


public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
//  该方法又向下调用了 registerOrEscalateApcAsRequired 方法
	return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}


<!--
    需要主要的是 该方法的 cls 是 AnnotationAwareAspectJAutoProxyCreator.class 类型的,后面还要具体分析.
-->
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
	Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

     <!--利用注册器查看容器中是否存在 AUTO_PROXY_CREATOR_BEAN_NAME("org.springframework.aop.config.internalAutoProxyCreator") 的实例.-->
	if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
		BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
		if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
			int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
			int requiredPriority = findPriorityForClass(cls);
			if (currentPriority < requiredPriority) {
				apcDefinition.setBeanClassName(cls.getName());
			}
		}
		return null;
	}
<!--
    在容器中不存在的情况下,向容器内注册 一个 AUTO_PROXY_CREATOR_BEAN_NAME
    名字的bean实例
-->
	RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
	beanDefinition.setSource(source);
	beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
	beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
	registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
	return beanDefinition;
}

AnnotationAwareAspectJAutoProxyCreator.class 类图

从类图中发现 AnnotationAwareAspectJAutoProxyCreator 是一个后置处理器
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值