Цикл зависимостей Spring bean-компонентов - для преобразования из DAO в PropertiesFile и для преобразования - PullRequest
1 голос
/ 23 апреля 2020

Приложение My Spring Boot имеет преобразователь, зарегистрированный в ConversionService, который зависит от службы, которая, в свою очередь, зависит от Dao. Значение Dao зависит от аннотированного объекта @ConfigurationProperties, введенного в качестве параметра конструктора с именем hardwareProperties, который зависит от ConversionService. Как этот цикл можно разорвать?

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

┌─────┐
|  conversionService defined in class path resource [com/xxxx/services/AppConfiguration.class]
↑     ↓
|  activityMessageConverter (field private com.xxxx.services.cp.services.interfaces.SubscriptionService com.xxxx.services.cp.converters.ActivityMessageConverter.subscriptionService)
↑     ↓
|  subscriptionServiceImpl defined in file [D:\projectXXX\target\classes\com\xxxx\services\cp\services\SubscriptionServiceImpl.class]
↑     ↓
|  subscriptionDao defined in file [D:\projectXXX\target\classes\com\xxxx\services\cp\dao\SubscriptionDao.class]
↑     ↓
|  hardwareProperties
└─────┘

package com.xxxx.services;
import com.xxxx.services.cp.converters.ActivityMessageConverter;
public class AppConfiguration {

    @Bean
    public ConversionServiceFactoryBean conversionService(ActivityMessageConverter activityMessageConverter) {
        ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
        factoryBean.setConverters(Set.of(activityMessageConverter));
        factoryBean.afterPropertiesSet();
        return factoryBean;
    }
}

package com.xxxx.services.cp.converters;
import com.xxxx.services.cp.services.interfaces.SubscriptionService;
@Component
public class ActivityMessageConverter implements Converter<Message, Activity> { 

    @Autowired
    @Qualifier("subscriptionServiceImpl")
    private SubscriptionService subscriptionService;

    public SubscriptionService getSubscriptionService() {
        return subscriptionService;
    }

    public void setSubscriptionService(SubscriptionService subscriptionService) {
        this.subscriptionService = subscriptionService;
    }

    @Override
    public Activity convert(Message message) {
        // Implementation
    }
}


package com.xxxx.services.cp.services;
@Component
public class SubscriptionServiceImpl implements SubscriptionService {

    private SubscriptionService subscriptionDAO;

    public SubscriptionServiceImpl(@Qualifier(value = "subscriptionDao") SubscriptionService subscriptionDAO) {
        setSubscriptionDAO(subscriptionDAO);
    }

    public SubscriptionService getSubscriptionDAO() {
        return subscriptionDAO;
    }

    public void setSubscriptionDAO(SubscriptionService subscriptionDAO) {
        this.subscriptionDAO = subscriptionDAO;
    }
}

package com.xxxx.services.cp.dao;
import com.xxxx.services.cp.services.interfaces.SubscriptionService;
@Component
@Repository
public class SubscriptionDao implements SubscriptionService {

    private HardwareProperties hardwareProperties;

    public SubscriptionDao(HardwareProperties hardwareProperties) {
        this.hardwareProperties = hardwareProperties;       
    }
}

package com.xxxx.services.properties;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@PropertySource("classpath:hardware.properties")
@ConfigurationProperties(prefix = "hardware.api")
public class HardwareProperties {
    private String host;
    private Integer port;
    private String username;
    private String password;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public Integer getPort() {
        return port;
    }

    public void setPort(Integer port) {
        this.port = port;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

}

// Usage of conversionService.
processMessages(context,
                filteredMessages.stream()
                        .map(message -> this.conversionService.convert(message, Activity.class))
                        .collect(Collectors.toList()));

1 Ответ

0 голосов
/ 23 апреля 2020

Вы пытаетесь изменить метод AppConfiguration с помощью сниппета:

@Bean
public ConversionServiceFactoryBean conversionService() {
    ConversionServiceFactoryBean factoryBean = new ConversionServiceFactoryBean();
    factoryBean.setConverters(Set.of(activityMessageConverter));
    factoryBean.afterPropertiesSet();
    return factoryBean;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...