Injeção de dependência baseada em Spring Setter
A DI baseada em setter é realizada pelo contêiner chamando métodos setter em seus beans após invocar um construtor sem argumento ou método de fábrica estático sem argumento para instanciar seu bean.
Exemplo
O exemplo a seguir mostra uma classe TextEditor que só pode ser injetada em dependência usando injeção baseada em setter puro.
Vamos ter um Eclipse IDE funcionando e seguir os seguintes passos para criar um aplicativo Spring -
Passos | Descrição |
---|---|
1 | Crie um projeto com um nome SpringExample e crie um pacote com.tutorialspoint sob osrc pasta no projeto criado. |
2 | Adicione as bibliotecas Spring necessárias usando a opção Adicionar JARs externos, conforme explicado no capítulo Exemplo do Spring Hello World . |
3 | Crie classes Java TextEditor , SpellChecker e MainApp no pacote com.tutorialspoint . |
4 | Crie o arquivo de configuração do Beans Beans.xml sob osrc pasta. |
5 | A etapa final é criar o conteúdo de todos os arquivos Java e do arquivo de configuração do Bean e executar o aplicativo conforme explicado abaixo. |
Aqui está o conteúdo de TextEditor.java arquivo -
package com.tutorialspoint;
public class TextEditor {
private SpellChecker spellChecker;
// a setter method to inject the dependency.
public void setSpellChecker(SpellChecker spellChecker) {
System.out.println("Inside setSpellChecker." );
this.spellChecker = spellChecker;
}
// a getter method to return spellChecker
public SpellChecker getSpellChecker() {
return spellChecker;
}
public void spellCheck() {
spellChecker.checkSpelling();
}
}
Aqui você precisa verificar a convenção de nomenclatura dos métodos setter. Para definir uma variávelspellChecker Nós estamos usando setSpellChecker()método que é muito semelhante às classes POJO Java. Vamos criar o conteúdo de outro arquivo de classe dependenteSpellChecker.java -
package com.tutorialspoint;
public class SpellChecker {
public SpellChecker(){
System.out.println("Inside SpellChecker constructor." );
}
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
A seguir está o conteúdo do MainApp.java arquivo -
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
TextEditor te = (TextEditor) context.getBean("textEditor");
te.spellCheck();
}
}
A seguir está o arquivo de configuração Beans.xml que tem configuração para a injeção baseada em setter -
<?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-3.0.xsd">
<!-- Definition for textEditor bean -->
<bean id = "textEditor" class = "com.tutorialspoint.TextEditor">
<property name = "spellChecker" ref = "spellChecker"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"></bean>
</beans>
Você deve notar a diferença no arquivo Beans.xml definido na injeção baseada no construtor e na injeção baseada no setter. A única diferença está dentro do elemento <bean>, onde usamos as tags <constructor-arg> para injeção baseada no construtor e as tags <property> para injeção baseada no setter.
O segundo ponto importante a observar é que, caso você esteja passando uma referência a um objeto, você precisa usar ref atributo da tag <property> e se você está passando um value diretamente, então você deve usar o atributo value.
Assim que terminar de criar os arquivos de configuração de código-fonte e bean, vamos executar o aplicativo. Se estiver tudo bem com o seu aplicativo, a seguinte mensagem será impressa -
Inside SpellChecker constructor.
Inside setSpellChecker.
Inside checkSpelling.
Configuração XML usando p-namespace
Se você tiver muitos métodos de setter, é conveniente usar p-namespaceno arquivo de configuração XML. Vamos verificar a diferença -
Vamos considerar o exemplo de um arquivo de configuração XML padrão com tags <property> -
<?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-3.0.xsd">
<bean id = "john-classic" class = "com.example.Person">
<property name = "name" value = "John Doe"/>
<property name = "spouse" ref = "jane"/>
</bean>
<bean name = "jane" class = "com.example.Person">
<property name = "name" value = "John Doe"/>
</bean>
</beans>
A configuração XML acima pode ser reescrita de uma forma mais limpa usando o namespace p da seguinte maneira -
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:p = "http://www.springframework.org/schema/p"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id = "john-classic" class = "com.example.Person"
p:name = "John Doe"
p:spouse-ref = "jane"/>
</bean>
<bean name =" jane" class = "com.example.Person"
p:name = "John Doe"/>
</bean>
</beans>
Aqui, você deve notar a diferença na especificação de valores primitivos e referências de objeto com p-namespace. o-ref part indica que este não é um valor direto, mas sim uma referência a outro bean.