从配置文件解析参数?自定义注解来实现一下!

>>强大,10k+点赞的 SpringBoot 后台管理系统竟然出了详细教程!

点击关注公众号,利用碎片时间学习

文章概述

  • @Value@PropertySource注解中使用${}引用配置文件参数原理分析
  • 把这个功能加入到自己的注解中

问题分析

平时在使用@Value@PropertySource两个注解(下面分别用V和P代替)时都可以在value中使用${xxx.xxx}方式获取配置文件的值,这样可以使程序根据配置文件动态设置一些值,比如数据库连接的url,username,password或者环境变量等。

但是有时候自己实现的切面注解中也想能使用这样的方式动态配置,这就需要spring环境变量的解析支持了。

这两个注解的解析过程

V是在spring-bean中,P是在spring-context中,但是他们的${}解析过程都需要依赖Environment提供的环境解析

具体spring代码分析可以看这篇文章,这篇分析的已经很细致了,并指出了具体实现的地方我这里只列出具体实现的地方

https://blog.csdn.net/f641385712/article/details/91043955

public abstract class AbstractPropertyResolver implements ConfigurablePropertyResolver {
.....
 @Override
 public String resolvePlaceholders(String text) {
  return this.propertyResolver.resolvePlaceholders(text);
 }
 
 @Override
 public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
  return this.propertyResolver.resolveRequiredPlaceholders(text);
 }
....
}

就是resolvePlaceholders这个方法解析${}里的参数的。

如何加入到自己的注解中

spring中有个EnvironmentAware接口,他的作用就是在任何实现了这个接口的类中注入Environment对象,就可以在自己的类中使用这个对象的功能了,还有ApplicationContextAwareSchedulerContextAware等等,通过搜索spring-framework的源代码可以看到所有spring可以对外提供的这些内部工具接口。

使用方法很简单

import java.lang.annotation.*;
 
@Target(ElementType.METHOD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {
    String username() default "";
    String password() default "";
}
public class AspectDemo implements EnvironmentAware {
    Environment environment;
 
    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
 
    @Pointcut("@annotation(com.watson.onebox.aspect.annotations.Login)")
    public void logPointCut() {
 
    }
 
    @Before(value = "logPointCut()")
    public void check(){
        log.info("check");
    }
 
 
    @After(value = "logPointCut()")
    public void bye(){
        log.info("bye");
    }
 
    @Around("logPointCut() && @annotation(login)")
    public Object around(ProceedingJoinPoint joinPoint, Login login){
        log.info("around");
        //关键的就是这一行解析代码        
        String s = environment.resolvePlaceholders(login.username());
        log.info("username: {}", login.username());
        log.info("username-resolve: {}", s);
        //输出使用login注解时候的passwo属性值
        log.info("password: {}", login.password());
        Object proceed = null;
        try {
            proceed = joinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
 
}

这个就是完整的一个自己实现切面注解解析过程的代码。这样在使用注解时就可以通过${xxx.xxx}方式加载配置文件参数了

下面是测试代码,使用springboot启动就可以了

@Slf4j
@Component
public class TestMethod {
 
    @Login(username = "abc-${spring.profiles.active}", password = "b")
    public String getData() {
        log.info("get data");
        return "getData";
    }
}

来源:blog.csdn.net/zpzkitt/article/details/103418644

推荐:

主流Java进阶技术(学习资料分享)

从配置文件解析参数?自定义注解来实现一下!
PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。“在看”支持我们吧!

原文始发于微信公众号(Java笔记虾):从配置文件解析参数?自定义注解来实现一下!