使用spring boot的切面注解,来简化登录代码,以及java元注解基本知识

目录

 

 

目录

1. 自定义LoginInfo注解

1.0 元注解

1.1 @Inherited

1.2 @Retention

1.3 @Target

1.4 @Documented

2 代码解析

2.0 定义的Class InfoAscept以及使用的@Pointcut 以及@Aspect

2.1.1 @Pointcut @Before("infoCut()")

2.1.2 ServletRequestAttributes


 


1. 自定义LoginInfo注解

import java.lang.annotation.*;


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

1.0 元注解

 元注解(meta-annotation)

@Target,@Retention,@Documented,@Inherited

这四个标准的元注解,那么都是有相对应的使用功能的。

 

1.1 @Inherited

在这个注解中,

@Inherited:这是一个标注注解,@Inherited阐述了某个被标注的类型是被继承的。 
如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。 

(理解其实就是:

1.当有这个元注解修饰的注解,那么当它修饰 父类的时候,子类也会继承这个注解!!!

2.但是接口的继承关系中,子接口不会集成父接口的任何注解!!!不管注解有没有被@Inherited修饰

3.那么一个类实现一个接口呢?类实现接口时不会继承任何接口中定义的注解)(也就是只针对类与类之间的继承可以实现)

1.2 @Retention

官方代码:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}


public enum RetentionPolicy {
    SOURCE,
    CLASS,
    RUNTIME
}

Reteniton的作用是定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中~

SOURCE 被编译器忽略(就是源文件保留)

CLASS 注解将会被保留在Class文件中,但在运行时并不会被VM保留。这是默认行为,所有没有用Retention注解的注解,都会采用这种策略。

RUNTIME 保留至运行时。所以我们可以通过反射去获取注解信息。

转自 :https://blog.csdn.net/asdgbc/article/details/70196749

另外:javap是jdk自带的反解析工具。它的作用就是根据class字节码文件,反解析出当前类对应的code区(汇编指令)、本地变量表、异常表和代码行偏移量映射表、常量池等等信息。

1.3 @Target

@Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法参数和本地变量(如循环变量、catch参数)。在Annotation类型的声明中使用了target可更加明晰其修饰的目标。

其实就是明确修饰的目标!

取值(ElementType)有:

    1.CONSTRUCTOR:用于描述构造器
    2.FIELD:用于描述域 (仅可用于注解类的成员变量)
    3.LOCAL_VARIABLE:用于描述局部变量
    4.METHOD:用于描述方法 (比如controller中的方法)
    5.PACKAGE:用于描述包
    6.PARAMETER:用于描述参数
    7.TYPE:用于描述类、接口(包括注解类型) 或enum声明

1.4 @Documented

描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。Documented是一个标记注解,没有成员。

 

2 代码解析

2.0 定义的Class InfoAscept以及使用的@Pointcut 以及@Aspect

代码经过了处理,主要讲的一个思想hhh 大概只有我看得懂

@Aspect
@Component
@Slf4j
public class InfoAscept {

    @Pointcut(value = "@annotation(com.******.common.annotion.LoginInfo)")
    public void infoCut(){}

     @Before("infoCut()")
    public void before(){
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String authToken = request.getHeader("X-Auth-Token");
        if(StringUtils.isBlank(authToken)){
            throw new ResultException(***错误的常量***,"");
        }

        //向账户系统发送请求携带了token然后还有Threadlocal中的golobalrequestId
        //然后从账户系统中获得账户信息
        String res = HttpUtils.sendJsonPost("***脱敏***");
        AccountAuthTokenBaseData accountAuthTokenBaseData = JsonUtils.fromJson(res, AccountAuthTokenBaseData.class);
        if(SUCC != accountAuthTokenBaseData.getCode()){
            throw new ResultException(accountAuthTokenBaseData.getCode(), accountAuthTokenBaseData.getMsg(), "");
        }
        AccountAuthTokenData accountAuthTokenData = accountAuthTokenBaseData.getResult();
        ThreadLocal.setUserInfo(accountAuthTokenData);
    }
}

2.1.1 @Pointcut @Before("infoCut()")

@Pointcut :这个应该说是切点,举个例子:
一个类(Show)里面有一个表演(display)的方法,在表演之前,应该有致辞(say)的方法,在表演之后,应该有鼓掌(hand)的方法。

了高内聚低耦合,表演的方法应该单独封装在一个类里面,致辞和鼓掌的方法应该另外封装,但在调用时必须按照顺序来调用执行。这时候就需要设置切面和切点了!

切面应该设置在致辞(say)和鼓掌(hand)方法所在的类上面,同时,要在类里面配置切点

转自:https://blog.51cto.com/12181171/2103016

那么对于登录过程中 切点其实就是提取信息,那么写了一个空的切点方法,然后在切点之前获得了登录信息。

那么PointCut()里面应该有配置登录的方法的路径!!!

还可以有@AfterReturning方法,在标记方法执行完了之后执行的~

标记方法就是上述代码中的infoCut 也就是被@Pointcut注解注释的方法~

 

这些配置完成了之后,调用切入点方法的时候,就会先进行执行before 然后执行完了@AfterReturning。

还可以有@AfterThrowing 也就是当切点抛出异常之后执行的~

其他使用场景:调用不到一个类中的一个方法。然后也可以通过设置切点、切面来解决。

这是很浅层的理解,还需要更多的实践学习~

2.1.2 ServletRequestAttributes

在项目中用到的代码就是

ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();

也就是获取Request请求最终的目的!

然后这个request可以获取到一些header信息!

其实就是一种Spring MVC获取request 和response的方式!

感觉上因为这是写在了 controller之上的注解上,所以需要用

在Spring API中提供了工具类RequestContextHolder,能够在Controller中获取request对象和response对象,使用方法如下

HttpServletRequest req = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
HttpServletResponse resp = ((ServletWebRequest)RequestContextHolder.getRequestAttributes()).getResponse();

需要注意的是如果直接使用这个工具类,则会抛出一个空指针异常。原因是需要先在web.xml配置RequestContextListener监听器:

<listener>
      <listener-class>
          org.springframework.web.context.request.RequestContextListener
      </listener-class>
</listener>

参考:https://www.cnblogs.com/winner-0715/p/6270513.html

2.2 总结

这种来让API验证登录的方式比较简洁,只需要一个注解

然后ascept 其实是为了来实现这个注解的方法的

比如LogAscept  还有一些Ascept

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Spring Boot 中,可以使用 AOP(面向切面编程)来实现切面环绕。通过使用 AOP,我们可以在应用程序的不同部分添加横切关注点,而无需修改这些部分的源代码。 下面是一个示例,展示了如何在 Spring Boot使用 AOP 进行切面环绕: 1.首先,我们需要创建一个切面类,该类需要使用 @Aspect 注解进行标注。 ```java @Aspect @Component public class LoggingAspect { } ``` 2.在切面类中,我们需要创建一个环绕通知方法,该方法需要使用 @Around 注解进行标注。 ```java @Around("execution(* com.example.demo.service.*.*(..))") public Object logMethodExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); long endTime = System.currentTimeMillis(); logger.info(joinPoint.getSignature() + " executed in " + (endTime - startTime) + "ms"); return result; } ``` 3.在上面的代码中,我们使用 @Around 注解来标注 logMethodExecutionTime 方法,该方法将会在 service 包下的所有方法执行前后进行环绕通知。在方法中,我们记录了方法的执行时间,并通过日志打印出来。 4.最后,我们需要在 Spring Boot 应用程序启动类上添加 @EnableAspectJAutoProxy 注解来启用 AOP 功能。 ```java @SpringBootApplication @EnableAspectJAutoProxy public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 通过上述步骤,我们就可以在 Spring Boot 应用程序中使用 AOP 进行切面环绕了。 ### 回答2: Spring Boot是一个开发框架,可以简化Java开发过程。切面Spring AOP(面向切面编程)的一个重要概念。环绕通知则是AOP中一种通知类型。 在Spring Boot中,我们可以使用切面环绕来实现一些跨越多个模块的通用逻辑。切面环绕可以在目标方法执行之前和之后执行一些自定义的业务逻辑,同时也可以修改目标方法的返回值或处理异常。 首先,我们需要创建一个切面类,通过使用Spring提供的注解来定义切面的具体逻辑。我们可以使用@Aspect注解将一个类标记为切面类,接着使用@Before、@After、@Around等注解来定义对应的切入点和通知类型。 在切面类中,我们需要定义一个环绕通知的方法,并在方法上使用@Around注解。在环绕通知方法中,我们可以通过ProceedingJoinPoint参数来获取目标方法的信息。可以利用这个参数,在目标方法执行之前编写一些逻辑,在目标方法执行之后编写一些逻辑。同时,我们还可以通过proceed方法调用目标方法,并修改返回值或处理异常。 当定义好切面类后,我们需要在应用的配置类中启用切面。可以使用@EnableAspectJAutoProxy注解来启用切面的自动代理功能。这样,Spring Boot会自动根据切面类的注解配置生成对应的代理类,并在目标方法执行的时候,触发切面的逻辑。 总结来说,Spring Boot切面环绕是一种通过使用切面类来定义环绕通知,实现一些跨越多个模块的通用逻辑的方式。通过切面环绕可以在目标方法执行之前和之后编写自定义的业务逻辑,同时还可以修改返回值或处理异常。 ### 回答3: Spring Boot是一个用于构建独立的、生产级的Spring应用程序的框架。切面(Aspect)是Spring框架中的一个重要概念,用于对程序中的特定方法进行拦截、增强或修改等操作。 在Spring Boot使用切面环绕的方式,可以实现对目标方法进行前置、后置、异常和最终通知的处理。首先,我们需要创建一个切面类,并使用@Aspect注解进行标记。在切面类中,我们可以定义切点(Pointcut)和通知(Advice)。 切点指定了在何处拦截方法,可以使用@Pointcut注解进行定义。通知是在方法执行前后或发生异常时执行的一段代码,可以使用@Before、@After、@AfterReturning和@AfterThrowing等注解进行标记。在通知中,我们可以获取方法的参数、返回值和异常等信息,并根据需要进行处理。 除了使用注解方式,我们还可以通过编程方式配置切面环绕。可以继承org.aspectj.lang.annotation.AspectJProxyFactory类,并在其中添加切点和通知等配置。然后,通过该类的getProxy()方法获取代理对象,并使用代理对象调用目标方法。 在使用切面环绕时,我们可以通过在应用的配置文件中添加@EnableAspectJAutoProxy注解,来启用Spring的AOP功能。此外,我们还可以使用@Order注解来确定切面的执行顺序,使用@Around注解来实现对目标方法的环绕处理。 总之,Spring Boot切面环绕是一种强大的功能,它可以对程序中的特定方法进行拦截和增强等操作。通过使用切面环绕,我们可以实现非侵入式的功能扩展,提高代码的复用性和可维护性,并实现更好的业务逻辑控制。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值