F# передают описания типа

Да, вы можете сделать это с помощью вашей пользовательской реализации BeanFactoryPostProcessor.

Вот простой пример.

Предположим, что у нас есть две компоненты. Одна из них - зависимость для другой.

Первый компонент:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

 public class MyFirstComponent implements InitializingBean{

    private MySecondComponent asd;

    private MySecondComponent qwe;

    public void afterPropertiesSet() throws Exception {
        Assert.notNull(asd);
        Assert.notNull(qwe);
    }

    public void setAsd(MySecondComponent asd) {
        this.asd = asd;
    }

    public void setQwe(MySecondComponent qwe) {
        this.qwe = qwe;
    }
}

Как вы могли видеть, ничего особенного в этом компоненте нет. Он имеет зависимость от двух разных экземпляров MySecondComponent.

Второй компонент:

import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Qualifier;


@Qualifier(value = "qwe, asd")
public class MySecondComponent implements FactoryBean {

    public Object getObject() throws Exception {
        return new MySecondComponent();
    }

    public Class getObjectType() {
        return MySecondComponent.class;
    }

    public boolean isSingleton() {
        return true;
    }
}

Это немного сложнее. Вот две вещи, чтобы объяснить. Первый - @Qualifier - аннотация, содержащая имена компонентов MySecondComponent. Это стандартная, но вы свободны реализовать свои собственные. Позже вы увидите немного.

Второе, что нужно упомянуть, - это реализация FactoryBean. Если bean реализует этот интерфейс, он предназначен для создания некоторых других экземпляров. В нашем случае он создает экземпляры с типом MySecondComponent.

Самая сложная часть - реализация BeanFactoryPostProcessor:

import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;


public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        Map<String, Object> map =  configurableListableBeanFactory.getBeansWithAnnotation(Qualifier.class);
        for(Map.Entry<String,Object> entry : map.entrySet()){
            createInstances(configurableListableBeanFactory, entry.getKey(), entry.getValue());
        }

    }

    private void createInstances(
            ConfigurableListableBeanFactory configurableListableBeanFactory,
            String beanName,
            Object bean){
        Qualifier qualifier = bean.getClass().getAnnotation(Qualifier.class);
        for(String name : extractNames(qualifier)){
            Object newBean = configurableListableBeanFactory.getBean(beanName);
            configurableListableBeanFactory.registerSingleton(name.trim(), newBean);
        }
    }

    private String[] extractNames(Qualifier qualifier){
        return qualifier.value().split(",");
    }
}

Что она делает? Он проходит через все бобы, аннотированные с помощью @Qualifier, извлекает имена из аннотации и затем вручную создает бобы этого типа с указанными именами.

Вот конфигурация Spring:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="MyBeanFactoryPostProcessor"/>

    <bean class="MySecondComponent"/>


    <bean name="test" class="MyFirstComponent">
        <property name="asd" ref="asd"/>
        <property name="qwe" ref="qwe"/>
    </bean>

</beans>

Последнее, что нужно заметить здесь, хотя вы можете сделать это, вы не должны, если это не обязательно, потому что это не совсем естественный способ конфигурации. Если у вас более одного экземпляра класса, лучше придерживаться конфигурации XML.

29
задан Brian 4 September 2009 в 12:23
поделиться

3 ответа

Вы используете 'and':

type firstType = 
     | T1 of secondType

and secondType =
     | T1 of firstType
52
ответ дан 27 November 2019 в 20:38
поделиться

Я понял это. Это:


type firstType = 
     | T1 of secondType
     //................

and secondType =
     | T1 of firstType  
     //................   
3
ответ дан Max 14 October 2019 в 08:04
поделиться

Ограничение состоит в том, что типы должны быть объявлены в одном файле.

2
ответ дан 27 November 2019 в 20:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: