java - tag - Come si ottengono i fagioli creati dalla molla FactoryBean gestiti?



spring boot enable autowired (4)

FactoryBean può essere utilizzato per creare oggetti a livello di programmazione che potrebbero richiedere una logica di istanziazione complessa.

Tuttavia, sembra che i bean creati da FactoryBean non diventino gestiti a primavera. Questa interpretazione è corretta? Se è così, ci sono dei buoni stratagemmi? Un esempio di codice breve è incluso per illustrare il mio problema.

ApplicationContext:

<bean id="searcher" class="some.package.SearcherFactory" /> 
<bean id="service" class="some.package.Service" /> 

Implementazione di fabbrica:

public class SearcherFactory implements FactoryBean<Searcher> {

    @Override
    public Searcher getObject() throws Exception {
        return new Searcher(); // not so complex after all ;)
    }

    @Override
    public Class<Searcher> getObjectType() {
        return Searcher.class;
    }
    .... 
}

Classe creata dalla fabbrica:

public class Searcher() {
      private Service service;

      @Autowired
      public void setService(Service service) {
           // never invoked
           this.service=service;
      } 
}

https://src-bin.com


Answer #1

Che dire di questo ?

<bean id="serviceFactory"
      class="some.package.SearcherFactory" />


<bean id="service"
      factory-bean="serviceFactory"
      factory-method="getObject"/>

... e poi semplicemente iniettare il "servizio" del bean e non preoccuparti della fabbrica nel tuo codice


Answer #2

Ecco FactoryBean astratta di FactoryBean che esegue automaticamente l'autowiring:

public abstract class AbstractAutowiringFactoryBean<T> extends
    AbstractFactoryBean<T> implements ApplicationContextAware{

    private ApplicationContext applicationContext;

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

    @Override
    protected final T createInstance() throws Exception{
        final T instance = doCreateInstance();
        if(instance != null){
            applicationContext
              .getAutowireCapableBeanFactory()
              .autowireBean(instance);
        }
        return instance;
    }

    /**
     * Create the bean instance.
     * 
     * @see #createInstance()
     */
    protected abstract T doCreateInstance();

}

Estendilo, implementa i metodi getObjectType() e doCreateInstance() e sei attivo e in esecuzione con autowiring.

Nota: BeanPostProcessors non viene applicato, ciò richiederebbe un codice aggiuntivo.


Answer #3

No, anche i bean creati da FactoryBean sono gestiti dalla primavera.


Answer #4

Un modo manuale sarebbe:

  1. Inietta le dipendenze nel bean di fabbrica
  2. impostarli manualmente sull'oggetto di destinazione.

È inoltre possibile iniettare ApplicationContext nel bean factory (o ottenerlo implementando ApplicationContextAware ) e fare ctx.getAutowireCapableBeanFactory().autowireBean(bean)

Ammetto che entrambi si sentono strani, però.

Ma in effetti, se la logica è così semplice (solo l'istanziazione), usa l'ambito del prototype .





autowired