自己写的一个的注解,使用方便简洁^_^
源码地址: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