Injeção de dependência
A injeção de dependência é um design pattern que visa desacoplar os componentes da aplicação. Os componentes são instanciados externamente a classe. Um gerenciador controla essas instancias. Os componentes tem dependencias entre si. Esse gerenciador, através de uma configuração, liga os componentes de forma a montar a aplicação. Por exemplo:

    public class ExecutaQuery {

    	private Conexao conexao;

    	public void setConexao(Conexao conexao){
    		this.conexao = conexao;
    	}

    	public Conexao getConexao(){
    		return conexao;
    	}

    	(...)
    }

    public class Conexao {

    	(...)

    }

Suponhamos uma classe ExecutaQuery que execute queries em um banco de dados. Para executar uma query uma conexão com o banco de dados é necessária. Essa conexão é representada pela classe Conexao. A classe ExecutaQuery possui um setter para conexao, ela precisa de uma conexão com o banco de dados para executar as queries. Em um ambiente normal o código para criar e configurar seria como o exemplo:

    ExecutaQuery executaQuery = new ExecutaQuery();
    Conexao conexao = new Conexao();

    executaQuery.setConexao(conexao);

Para uma pequena aplicação esse código é simples. Mas em aplicações grandes com várias classes e várias dependências isso se torna bem complexo. O framework faz exatamente o que o código acima faz, mas o programador não precisa instanciar e nem configurar esses beans.
Um framework de injeção de dependencias irá criar e configurar os beans sem a necessidade de programação. O NEO utiliza para a injeção de dependências o framework Spring (www.springframework.org). O Spring possui uma fábrica que gerencia a criação e configuração dos beans. O NEO registra as classes nessa fábrica para a criação e configuração desses objetos. O NEO possui uma forma de registro de classes que dispensa o uso de XML, mas ainda é possível registrar os beans através do XML do Spring.
Configurando beans com annotations (@Bean)
Para utilizar a injeção de dependências é necessário uma fábrica que crie e configure os objetos da aplicação. Para a criação dessa fábrica é necessário a utilização de um listener (br.com.linkcom.neo.core.web.init.ContextLoaderListener) que deve ser configurado no web.xml. Esse listener cria e configura a fábrica do Spring. Essa classe extende o ContextLoaderListener do Spring. Portanto, qualquer configuração aplicável ao listener do Spring é também aplicavel ao NEO.
Exemplo de web.xml com o listener:

    [JSP]
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4"
    	xmlns="http://java.sun.com/xml/ns/j2ee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    	[ATTR]http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    	<listener>
    		<listener-class>br.com.linkcom.neo.core.web.init.ContextLoaderListener</listener-class>
    	</listener>

    </web-app>

Com o listener configurado podemos colocar beans na fábrica do Spring. O NEO permite a utilização de anotations para a configuração desses beans. Para configurar um bean para a fábrica basta anotar a classe com @Bean. Vamos voltar ao exemplo do ExecutaQuery e Conexao para ver como a configuração desses beans seria feita no NEO.

    import br.com.linkcom.neo.bean.annotation.Bean;

    @Bean
    public class ExecutaQuery {

    	private Conexao conexao;

    	public void setConexao(Conexao conexao){
    		this.conexao = conexao;
    	}

    	public Conexao getConexao(){
    		return conexao;
    	}

    	(...)
    }

    import br.com.linkcom.neo.bean.annotation.Bean;

    @Bean
    public class Conexao {

    	(...)

    }

O NEO detecta a presença da anotação @Bean e registra as classe na fábrica do Spring. Como a classe ExecutaQuery possui um setter para Conexao, ele será chamado passando como parâmetro a instancia de Conexao que foi criada. Apenas uma instancia de cada classe é criada, mesmo que mais de um objeto tenha dependencia de uma mesma classe. Os objetos no NEO são criados utilizando o design pattern singleton.
Note que, se a classe Conexao não estivesse anotada com @Bean nenhum bean da classe Conexao seria criado e o método setConexao(...) de ExecutaQuery não seria chamado.
Importante: Apenas as classes que estiverem dentro de /WEB-INF/classes serão registradas. O NEO não lê as classes que estiverem dentro de pacotes JAR dentro do lib da aplicação.
Para buscar os beans registrados na aplicação existem duas formas. Utilizando a factory do Spring:

    WebApplicationContext webApplicationContext = NeoWeb.getWebApplicationContext(servletContext);
    DefaultListableBeanFactory factory = webApplicationContext.getConfig().getDefaultListableBeanFactory();
    ExecutaQuery executaQuery = (ExecutaQuery) factory.getBean("executaQuery");

Buscando pelo NEO:

    NeoWeb.getWebApplicationContext(servletContext);
    ExecutaQuery executaQuery = Neo.getObject(ExecutaQuery.class);

O método getWebApplicationContext(...) é utilizado apenas para inicializar o contexto do NEO. O NEO possui dois contextos: de aplicação e de requisição. O contexto de aplicação é equivalente ao contexto de aplicação do J2EE e o contexto de requisição é equivalente ao contexto de requisição do J2EE. A fábrica do Spring é guardada no escopo de aplicação por isso é necessário inicializar o contexto de aplicação antes de buscar algum bean da fábrica.
Existe uma outra forma de utilizar o contexto NEO sem a necessidade de criá-lo explicitamente. Para utilizar essa forma é necessário cadastrar um filtro no web.xml:

    [JSP]
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.4"
    	xmlns="http://java.sun.com/xml/ns/j2ee"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    	[ATTR]http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    	<listener>
    		<listener-class>br.com.linkcom.neo.core.web.init.ContextLoaderListener</listener-class>
    	</listener>

    	<filter>
    		<filter-name>neoFilter</filter-name>
    		<filter-class>br.com.linkcom.neo.core.web.NeoFilter</filter-class>
    	</filter>
    	<filter-mapping>
    		<filter-name>neoFilter</filter-name>
    		<url-pattern>/*</url-pattern>
    	</filter-mapping>

    </web-app>

Com esse filtro, para utilizar um bean gerenciado basta utilizar o seguinte código:

    ExecutaQuery executaQuery = Neo.getObject(ExecutaQuery.class);

Passando apenas a classe desejada o NEO retorna um objeto configurado.
Nesse caso, a chamada:

    executaQuery.getConexao();

Retornaria uma instancia de Conexao. Já que ela foi configurada através da injeção de dependencias em ExecutaQuery.
Configurando relacionamentos
Apenas o fato de colocar um setter para uma propriedade faz com que o NEO configure automaticamente a classe. Mas é possível escolher qual bean utilizar para configurar determinada propriedade. A escolha de qual bean configurar em determinada propriedade pode ser útil em alguns casos.
Vamos entender como funciona a fábrica do Spring.
A fábrica do Spring contém uma coleção de todas as classes e configurações para instanciar os beans. Cada configuração dentro dessa fábrica representa um bean. Uma configuração deve definir no mínimo um nome e uma classe. É possível ter, dentro de uma fábrica, vários beans de uma mesma classe. Mas cada configuração deve ter um nome diferente. Por isso, o que identifica um bean dentro da fábrica é o seu nome.
Quando utilizamos a anotação @Bean o nome que a classe é registrada no Spring é o nome simples da classe (sem o pacote) com a primeira letra minúscula. Se temos uma classe a.b.c.MinhaClasse anotada com @Bean o nome que essa classe será registrada será 'minhaClasse'.
A anotação @Bean permite que o nome de registro do bean seja alterado através da propriedade name. Veja o exemplo:

    import br.com.linkcom.neo.bean.annotation.Bean;

    @Bean(name="c")
    public class Conexao {
    }

Agora para conseguir um bean de Conexao o nome informado deve ser 'c'. Exemplo:

    DefaultListableBeanFactory factory = Neo.getApplicationContext().getConfig().getDefaultListableBeanFactory();
    Conexao conexao = (Conexao) factory.getBean("c");

Não é possível utilizar o método resumido do NEO (Neo.getObject(...)) para buscar beans cujo nome não seja o nome da classe com a primeira letra minúscula.
Dica: Utilize a anotação @Bean sem a propriedade name, isso faz com que o código fique mais limpo e seja possível utilizar a forma resumida do NEO para buscar os beans.
Para alterar o mapeamento de alguma propriedade utilizamos a anotação @Ref no setter da propriedade. Exemplo:

    import br.com.linkcom.neo.bean.annotation.Bean;

    @Bean
    public class ExecutaQuery {

    	private Conexao conexao;

    	@Ref("c")
    	public void setConexao(Conexao conexao){
    		this.conexao = conexao;
    	}

    	public Conexao getConexao(){
    		return conexao;
    	}

    	(...)
    }

Nesse caso estamos configurando a propriedade conexao com o bean 'c'. Se não existir o bean 'c' na fábrica do Spring uma exeção será lançada ao iniciar a aplicação.
Configurando beans através de XML
Apesar de não ser necessário, a configuração de beans pode também ser feita através do XML do Spring. No neo o xml padrão é o applicationConfig.xml. Esse xml deve ficar dentro da pasta /WEB-INF/ da aplicação.
Importante: No Spring o xml de configuração padrão é applicationContext.xml no Neo é applicationConfig.xml
Exemplo de XML de configuração:

    [JSP]
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

    <beans>
    .
    .
    .
    </beans>

Esse XML pode ser útil para fazer configurações de banco de dados e envio de e-mail por exemplo. A configuração desse XML é igual a configuração de um XML do Spring que não esteja utilizando o NEO. Para mais informações sobre a configuração via XML do Spring visite o site www.springframework.org
Organização da aplicação
Em uma aplicação profissional é importante separar as tarefas diferentes em classes diferentes. No neo é recomendada a utilização da seguinte organização:

- Controller - Recebe as requisições, faz o mínimo necessário e envia para a visão. Os controllers devem passar qualquer tipo de calculo ou regra de negócio para os services. Representado no NEO pela classe MultiActionController.
- Service - Efetua as regras de negócio. Se precisar de alguma informação persistente, pede aos DAOs. Representado no NEO pela classe GenericService.
- DAO - Efetua pesquisas no banco de dados. Representado no NEO por GenericDAO.

Qualquer classe que extender MultiActionController, GenericService ou GenericDAO não precisa ser anotada com @Bean. Uma explicação melhor sobre essas classes será feita nos capítulos seguintes.