写一个自己的注解@MyConfiguration,读取配置文件

自己写的一个的注解,使用方便简洁^_^

源码地址https://github.com/bigBigRiver/MyConfiguration.git

config.properties文件

userName=engineerdong
password=123456

配置文件对应的实体类 

import com.river.boot.annotation.MyConfiguration;
import lombok.Data;
import org.springframework.stereotype.Component;

@Data
@Component
@MyConfiguration(value = "/config.properties")
public class MyConfig {
    private String userName;
    private String password;
}

 测试类:

@Slf4j
@SpringBootTest
class BootApplicationTests {

    @Autowired
    MyConfig myConfig;

    @Test
    void logSomething() {
        log.info(myConfig.getUserName() + ":" + myConfig.getPassword());
    }

}

打印:

com.river.boot.BootApplicationTests 2020年01月10日 22:56:58 -- engineerdong:123456

注解类:

/**
 * @author river
 * 2020/1/10
 */
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyConfiguration {
    String value() default "application.properties";
}

注解类处理类(springboot):

import com.river.boot.annotation.MyConfiguration;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;

/**
 * 在springboot初始化的时候,通过java反射机制,为配置有@MyConfiguration注解的类的字段赋值
 *
 * @author river
 * 2020/1/10
 */
@Slf4j
@Component
public class HandleMyConfigurationRunner implements CommandLineRunner, ApplicationContextAware {

    private ApplicationContext applicationContext;

    private Properties configProperties = new Properties();

    @Override
    public void run(String... args) throws Exception {
        /*在容器中搜索被@MyConfiguration修饰的所有类名*/
        String[] configNames = applicationContext.getBeanNamesForAnnotation(MyConfiguration.class);
        if (StringUtils.isEmpty(configNames)) {
            return;
        }
        Object[] configObjects = new Object[configNames.length];

        /*在spring容器中获取类名对应的对象*/
        for (int i = 0; i < configNames.length; i++) {
            configObjects[i] = applicationContext.getBean(configNames[i]);
        }
        for (Object object : configObjects) {
            Class<?> clazz = object.getClass();
            MyConfiguration myConfiguration = clazz.getAnnotation(MyConfiguration.class);
            /*获取注解的value值并获取输入流*/
            String path = "/" + myConfiguration.value();
            InputStream inputStream = clazz.getResourceAsStream(path.replaceAll("/+", "/"));
            if (null == inputStream) {
                log.info("未找到资源:" + path);
                return;
            }
            configProperties.load(inputStream);

            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);//访问private字段
                field.set(object, configProperties.getProperty(field.getName()));//获取字段名并查询字段名在配置文件中对应的value,再设置到字段中去
            }
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

这样新增配置文件的时候,再新建一个实体类与配置文件对应即可以使用,挺方便的!

说明:

如果不是springboot项目,可以使用ApplicationListener来实现注解类处理类,如下:

import com.good.frame.annotation.MyConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;

@Component
public class ConfigListener implements ApplicationListener<ContextRefreshedEvent> {

    private ApplicationContext applicationContext;

    private Properties configProperties = new Properties();

    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        applicationContext = contextRefreshedEvent.getApplicationContext();
        try {
            handleMyConfiguration();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void handleMyConfiguration() throws Exception {
        /*在容器中搜索被@MyConfiguration修饰的所有类名*/
        String[] configNames = applicationContext.getBeanNamesForAnnotation(MyConfiguration.class);
        if (StringUtils.isEmpty(configNames)) {
            return;
        }
        Object[] configObjects = new Object[configNames.length];

        /*在spring容器中获取类名对应的对象*/
        for (int i = 0; i < configNames.length; i++) {
            configObjects[i] = applicationContext.getBean(configNames[i]);
        }
        for (Object object : configObjects) {
            Class<?> clazz = object.getClass();
            MyConfiguration myConfiguration = clazz.getAnnotation(MyConfiguration.class);
            /*获取注解的value值并获取输入流*/
            String path = "/" + myConfiguration.value();
            InputStream inputStream = clazz.getResourceAsStream(path.replaceAll("/+", "/"));
            if (null == inputStream) {
                System.out.println("未找到资源:" + path);
                return;
            }
            configProperties.load(inputStream);

            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);//访问private字段
                field.set(object, configProperties.getProperty(field.getName()));//获取字段名并查询字段名在配置文件中对应的value,再设置到字段中去
            }
        }
    }
}

关于@Data的使用,可以参考:https://blog.csdn.net/river66/article/details/103727367

关于@Slf4j的使用,可以参考:https://blog.csdn.net/river66/article/details/103713397

觉得有用的老铁赞一下呗~

发布了78 篇原创文章 · 获赞 131 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/river66/article/details/103931789