自定义属性无法在弹簧引导中注入

时间:2018-06-01 02:57:35

标签: java spring spring-boot

我只想在spring boot中实现自定义属性注入。但它确实如此 不太好用。 首先,我创建一个如下面的注释

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ConfigValue {
    String name();
}

其次,我创建了一个带有自定义注释的配置类,如下面的

@Configuration
public class MysqlConf {
@Value("${spring.datasource.driverClassName}")
private String className;
@Value("${spring.datasource.url}")
private String jdbcUrl;
@Value("${spring.datasource.username}")
private String username;
@ConfigValue(name = "spring.datasource.password")
private String password;

@Bean
public DataSource druidDataSource() {
    DruidDataSource druidDataSource = new DruidDataSource();
    druidDataSource.setDriverClassName(className);
    druidDataSource.setUsername(username);
    druidDataSource.setPassword(password);
    druidDataSource.setUrl(jdbcUrl);
    druidDataSource.setMaxActive(20);
    druidDataSource.setInitialSize(1);
    druidDataSource.setMinIdle(1);
    druidDataSource.setMaxWait(60000);
    druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
    druidDataSource.setMinEvictableIdleTimeMillis(300000);
    druidDataSource.setValidationQuery("select 1");
    druidDataSource.setTestWhileIdle(true);
    druidDataSource.setTestOnBorrow(false);
    druidDataSource.setTestOnReturn(false);
    druidDataSource.setPoolPreparedStatements(true);
    druidDataSource.setMaxPoolPreparedStatementPerConnectionSize(50);

    return druidDataSource;
 }

}

然后我设置如下的自定义属性

@Component
public class BeanPropertiesUtil  implements 
InitializingBean,BeanFactoryAware {

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

private BeanFactory beanFactory;

public static Map<String,Object> configMap = new HashMap<>();

@PostConstruct
public void init() throws Exception {
   configMap.put("spring.datasource.password","123321");
   configMap.put("orderNo","2018051929991");
}

@Override
public void afterPropertiesSet() throws Exception {
    logger.info("config map : "+ JSON.toJSONString(configMap));
    ApplicationContext applicationContext = 
        BeanNameUtil.getApplicationContext();
    final String[] beanDefinitionNames = 
        applicationContext.getBeanDefinitionNames();
    for(String beanName : beanDefinitionNames) {
        Object bean = beanFactory.getBean(beanName);
        final Field[] declaredFields = bean.getClass().getDeclaredFields();
        if(declaredFields.length > 0) {
            for(Field field : declaredFields) {
                final ConfigValue configValue = 
                    field.getAnnotation(ConfigValue.class);
                if(configValue != null) {
                    field.setAccessible(true);
                    logger.info("field name :"+field.getName() +" field 
                       value:"+configMap.get(configValue.name()));
                    field.set(bean,configMap.get(configValue.name()));
                }
            }
        }
    }
}

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    this.beanFactory = beanFactory;
}

}

它无法获取密码值,我还创建了另一个类

@Service
public class MyAnnotationService {

@ConfigValue(name = "spring.datasource.password")
private String password;

public void deSth() {
    System.err.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx:"+password);
  }
}

它有效, 我不知道为什么MysqlConf无法获得该值,但MyAnnotationService可以。请帮助我,谢谢!

1 个答案:

答案 0 :(得分:0)

bean.getClass().getDeclaredFields();

不返回@Configuration MysqlConf类的字段,如果你将MysqlConf更改为@Service

,它会起作用