【Annotation】SpringBoot自定义注解

1. 自定义注释是基于SpringAOP实现的

Spring AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架中的一个强大功能模块,它实现了AOP编程模型,允许开发者将横切关注点(如日志记录、事务管理、安全性检查、性能监控等)从业务逻辑中分离出来,以提高代码的模块化程度、可维护性和可重用性。

核心概念

  • 切面(Aspect):切面是跨越多个对象的关注点模块化方式的实现。它封装了横切关注点,比如事务管理就是企业级应用中的一个关注点,它可能会影响到多个对象的操作。
  • 连接点(Joinpoint):在程序执行过程中的某个特定点,如方法调用或异常抛出等,其中可以插入切面代码。Spring AOP只支持方法执行作为连接点。
    切入点(Pointcut):切入点定义了切面在何处应用,即匹配连接点的一组规则。通过表达式来指定哪些方法或类应该被切面影响。
  • 通知(Advice):在切面识别到特定的连接点时执行的动作。有五种类型的通知:
    • 前置通知(Before):在目标方法被调用之前执行。
    • 后置通知(After):在目标方法执行完毕后(无论是否发生异常)执行。
    • 返回通知(AfterReturning):在目标方法成功执行后执行。
    • 异常通知(AfterThrowing):在目标方法抛出异常后执行。
    • 环绕通知(Around):围绕着目标方法执行,在方法调用前后都可以进行自定义操作,还可以决定是否继续执行目标方法。
  • 织入(Weaving):将切面代码插入到应用程序代码中的过程。Spring AOP支持两种织入方式:编译期织入和运行时织入,Spring采用的是运行时织入,即在应用运行时通过动态代理来实现。
    实现方式

Spring AOP提供了两种代理方式来实现切面逻辑的织入:

  • JDK动态代理:当目标对象实现了至少一个接口时,Spring会使用JDK动态代理技术创建代理对象。这种方式的代理对象需要与目标对象实现相同的接口。
  • CGLIB代理:如果目标对象没有实现接口,Spring会使用CGLIB库来创建目标对象的子类代理。这种方式对于没有接口的类同样适用,但要求目标类不能是final的,且必须有默认构造函数。

使用Spring AOP

在Spring中使用AOP,通常涉及定义切面类(使用@Aspect注解标记)、定义切入点(使用@Pointcut注解)、以及在切点上应用通知(使用如@Before、@After等注解)。通过这些配置,Spring框架会在运行时自动创建代理对象,将切面逻辑编织进目标对象的方法调用流程中,从而实现非侵入式的横切关注点管理。

2. 使用自定义注释

步骤1: 定义自定义注解

首先,我们定义一个自定义注解@LogExecutionTime,用于标记需要记录执行时间的方法。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}

步骤2: 创建切面类

接着,我们创建一个切面类LoggingAspect,使用@Aspect注解标记,并在其中定义切点和通知逻辑。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class);

    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();

        Object proceed = joinPoint.proceed(); // 执行原方法

        long elapsedTime = System.currentTimeMillis() - start;
        logger.info("Method {} executed in {} ms", joinPoint.getSignature().getName(), elapsedTime);

        return proceed;
    }
}

步骤3: 应用自定义注解

现在,我们可以在任何想要记录执行时间的方法上使用@LogExecutionTime注解。

@Service
public class MyService {

    @LogExecutionTime
    public String performTask() {
        // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }
        
        return "Task completed!";
    }
}

步骤4: 配置Spring启用AOP

确保Spring知道要使用AOP。

@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
    // 其他配置...
}
  • 13
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot是一个用于构建独立的、生产级别的Spring应用程序的框架。它提供了许多便捷的功能和特性,其中包括自定义注解配置。 在Spring Boot中,我们可以通过自定义注解来实现一些特定的配置。下面是一个简单的示例来介绍如何自定义注解配置: 1. 首先,创建一个自定义注解类,使用`@interface`关键字来定义注解。例如,我们创建一个名为`@CustomAnnotation`的注解: ```java import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface CustomAnnotation { String value() default ""; } ``` 2. 在需要使用该注解的类上添加注解。例如,我们创建一个名为`CustomClass`的类,并在类上添加`@CustomAnnotation`注解: ```java @CustomAnnotation("customValue") public class CustomClass { // 类的具体实现 } ``` 3. 在Spring Boot的配置类中,使用`@ComponentScan`注解来扫描带有自定义注解的类,并进行相应的配置。例如: ```java @SpringBootApplication @ComponentScan(basePackages = "com.example") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } ``` 4. 在需要使用自定义注解的地方,可以通过反射获取注解的值,并进行相应的处理。例如,在某个Service类中使用自定义注解: ```java @Service public class CustomService { @Autowired private ApplicationContext applicationContext; public void processCustomAnnotation() { Map<String, Object> customBeans = applicationContext.getBeansWithAnnotation(CustomAnnotation.class); for (Object bean : customBeans.values()) { CustomAnnotation customAnnotation = bean.getClass().getAnnotation(CustomAnnotation.class); String value = customAnnotation.value(); // 处理自定义注解的逻辑 } } } ``` 这样,我们就可以通过自定义注解来实现一些特定的配置。在上述示例中,我们通过自定义注解`@CustomAnnotation`来标记需要进行特定处理的类,并在`CustomService`中通过反射获取带有该注解的类,并进行相应的处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CRE_MO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值