Pergunta

Existe uma maneira de Spring beans auto-cast para a classe definido no XML contexto de aplicação? Eu gostaria de evitar colocar informações de tipo sobre o feijão em 2 lugares .... no arquivo de configuração XML e também no código como um elenco.

Por exemplo, dado este arquivo de configuração

<bean id="bean-name" class="SimpleSpringBean"  scope="prototype">
    <property name="myValue" value="simple value"></property>
</bean>

Can I chamada ApplicationContext.getBean("bean-name") de tal forma a evitar diretamente lançando o tipo de retorno para SimpleStringBean. Eu sei que eu também pode ligar ApplicationContext.getBean("bean-name", SimpleSpringBean.class) para evitar o próprio elenco, mas ainda tenho a informação tipo em 2 lugares.

Parece que Primavera pode obter a informação de classe (ApplicationContext.getType) ou obtendo o tipo do próprio feijão, mas não há maneira de automaticamente lançar o tipo sem a intervenção do programador.

Foi útil?

Solução

Eu concordo com Sii, você deve evitar chamar getBean tanto quanto você pode. Apenas ligar o seu feijão para classes que depende deles.

Ainda assim, se você tem uma única classe que contém o contexto do aplicativo, você pode fornecer um invólucro método genérico como o seguinte:

class MyContextHolder{
    ApplicationContext appContext;
    ......
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanName)
    {
        return (T)appContext.getBean(beanName);
    }
}

Em seguida, você pode chamá-lo sem lançar

MyClass mc = MyContextHolder.getBean("myClassBean");

Outras dicas

A resposta é que você não deve estar usando ApplicationContext.getBean () em todos, se é possível, e urso com o único lugar que você tem que no código de inicialização. (Geralmente, você nunca deve precisar usar fora dos pontos de entrada da sua aplicação getBean ().)

Além disso, o que você está pedindo é provavelmente impossível na linguagem Java em tudo. A carcaça é uma característica de tempo de compilação, combinado com um controlo de tempo de execução. O tipo de retorno getBean () simplesmente deve ser conhecido em tempo de compilação. Mesmo que Primavera pode determinar o tipo de um objeto, ele não pode mudar suas próprias assinaturas de método em tempo de execução.

Outra coisa é que, mesmo se isso fosse possível, o recurso não seria tão útil. Porque Spring AOP é implementado usando proxies dinâmicos, você quase sempre quer Primavera para entregar-lhe um exemplo de uma interface os implementos de feijão (que poderia ser um proxy AOP), não da classe de implementação.

Outra abordagem que eu também uso é autowiring a classe bootstrapping usando:

public class Main {
    @Autowired FooFacade foo;
    @Autowired BarFacade bar;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("appCtx.xml");
        AutowireCapableBeanFactory bf = ctx.getAutowireCapableBeanFactory();
        Object main = bf.createBean(Main.class, 
                                    AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT,
                                    false);
        ((Main) main).run();
    }

    private void run() {
        foo.doBootstrapStuff();
        bar.doMoreBootstrapStuff();
    }
}

(Código feito a partir da memória. Talvez só funcionam se você tiver o contexto da Primavera configurado para anotações de fiação processo, nesse caso fazendo setters para foo e bar deve funcionar.)

A principal razão para getBean sendo untyped é a compatibilidade da Primavera (até a versão 2.5.x) com Java 1.4. Spring 3.0 vai cair isso e, assim, oferecer método getBean digitado então.

No entanto, você deve evitar olhando para cima grãos diretamente e minimizar seu uso, tanto quanto possível.

E se eu usar o Spring como uma fábrica de objeto que meu aplicativo usa extensivamente. Ou seja, em vez de escrever um monte de classes que já herdar ou envolver classes Java conhecidos Eu só decidir mudar tudo isso em um arquivo xml para reduzir linhas de código Java. Isto significa muitas linhas de xml, mas não vou precisar fazer aulas de Java esqueleto que eu injectam com mola ou autowire. Assim, fazendo as linhas de código Java a menos.

Por esta razão e ainda como eu sou novo para Primavera acabo como indicado na anterior mensagens usado métodos Java estáticos que envolvem em torno dos getBeans ().

Eu tenho trabalhado com a Primavera, mas ainda é nova para mim, então perdoe a minha pergunta.

"Porque Spring AOP é implementado usando proxies dinâmicos, você quase sempre quer Primavera para entregar-lhe um exemplo de uma interface os implementos de feijão (que poderia ser um proxy AOP), não da classe de implementação"

Portanto, não há maneira de obter um proxy dinâmico usando getBean (), então o que é a melhor prática se não houver interfaces e seu um pé de classe do driver sozinho para ser executado?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top