Os dois principais recursos do framework Spring são IoC (Inversão de Controle) e AOP (Programação Orientada a Aspectos).
O Spring adota um design não intrusivo, ou seja, quando usamos o framework Spring, não há herança virtual de nenhuma classe fornecida pelo framework, o que garante que o código não precise ser refatorado em grande medida quando o framework é substituído.
O Spring é leve, não intrusivo, tem muito poucas dependências, poucos recursos e implantação simples.
Inversão de controle: o controle de objetos criados manualmente no programa é gerenciado pelo Spring, e você não precisa se preocupar com a criação do objeto. Você pode retirá-lo diretamente do container Spring quando necessário, ou seja, fornecer o controle de criação do objeto Spring, inversão de controle.
1. Importar dependências
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
<!--引入web会将所有的spring相关依赖全部导入-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
</dependencies>
2. Defina uma classe que esteja em conformidade com a especificação JavaBean (o objeto de classe de entidade que está em conformidade com a especificação pode ser gerenciado pelo contêiner Spring)
A. JavaBean: JavaBean é um componente reutilizável escrito em linguagem JAVA. É uma classe Java escrita em conformidade com certas especificações. Não é uma tecnologia, mas uma especificação. As classes que estão em conformidade com esta especificação podem ser usadas por outros programadores ou estruturas. A nomenclatura, a estrutura e o comportamento de seu método devem obedecer a convenções específicas:
1. Todos os atributos são privados.
2. Essa classe deve ter um construtor público sem parâmetros.
3. Use getters e setters para acessar as propriedades desta classe.
4. Implemente a interface serializável.
package com.zt.pojo;
public class User {
private String name;
public User() {
}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void sayHello(){
System.out.println("Hello," + name);
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
B. Ao aprender o modelo de desenvolvimento MVC, estamos acostumados a chamar POJOs de classes de entidade: (Objeto Java comum simples) objetos Java simples, nenhum método de negócios é permitido e métodos como conexão não podem ser transportados. Eles são, na verdade, JavaBeans comuns, POJOs O nome é uma abreviatura criada para evitar confusão com EJB. Claro, ainda existem pequenas diferenças.JavaBean pode ter alguns métodos simples e os POJOs não podem ter outros métodos, exceto para propriedades, construção, getters e setters.
package com.zt.pojo;
public class User {
private String name;
public User() {
}
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}
C. Entidade: uma classe de entidade corresponde a uma tabela de dados, que é usada para mapeamento ORM. Os atributos nela correspondem aos campos na tabela de dados. Ao passar parâmetros, você pode armazenar os parâmetros na classe de entidade para passar a entidade Além de estar relacionado ao banco de dados, Outros são quase iguais ao POJO.
3. Grave o arquivo de configuração
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.zt.entity.User">
<property name="name" value="zzt"/>
</bean>
</beans>
xmlns é o namespace xml std, que é usado para apresentar alguns arquivos de ligação para garantir que o arquivo xml esteja em conformidade com as especificações definidas oficialmente.
xmlns: xsi é um namespace com o prefixo xsi, que é usado para tags com o mesmo nome sob diferentes tipos de restrições. Para garantir a resolução correta, usamos identificadores para distinguir tags duplicadas, <xsi: tag name>. Nenhum indicador significa o namespace padrão, o namespace padrão do Spring é <bean: tag name>.
tag <bean>: id representa a identidade deste objeto no tipo de classe de contêiner deste objeto
Tag <property>: usada para atribuir um valor ao objeto da classe de entidade, name é o nome da propriedade e value é o valor da propriedade correspondente. O leitor deve refletir que a atribuição aqui usa o configurador correspondente ao atributo .
4. Escrever testes
@Test
public void testCreateBean(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
}
Depois de ler e analisar o arquivo de configuração, o container Spring applicationContext é gerado e a classe de entidade criada pelo container pode ser obtida fornecendo o id e o tipo por meio do método getBean do container.
ClassPathXmlApplicationContext: O carregador de recursos do classpath.Em um projeto Maven, o java e os recursos no diretório principal serão colocados no classpath após a compilação.
Obviamente, o Spring também fornece um carregador para carregar recursos em outros lugares: FileSystemXmlApplicationContext. Mas não é comumente usado, porque geralmente não colocamos o arquivo de configuração do projeto fora do projeto.
Inversão de controle vs. injeção de dependência: a inversão de controle é uma ideia que transfere o controle de classes de entidade do programador para o contêiner Spring. A injeção de dependência é a principal forma de obter a inversão de controle; em programas, muitas vezes há classes de entidade. Conexão e acoplamento mútuo. O processo de desenvolvimento tradicional é mantido por programadores. Uma vez que uma classe tem um problema, outra classe precisa ser modificada onde ela é usada. O motivo é que vinculamos manualmente sua relação de associação; enquanto o contêiner Spring permite ao programador configure diretamente quais estão relacionadas, e o container é responsável pela efetiva realização da associação. Quando quisermos substituir as classes utilizadas, basta modificar o arquivo de configuração diretamente, sem ter que alterar cada Modifique o código onde for utilizado.
Vamos dar um exemplo. Agora, há dois alunos que têm métodos de execução, mas seus comportamentos são completamente diferentes. O professor emite o comando run para que o código possa ser escrito pressionando:
public interface Stu {
public void run();
}
public class StuA implements Stu{
public void run(){
System.out.println("A跑的很快");
}
}
public class StuB implements Stu{
public void run(){
System.out.println("B跑的很慢");
}
}
public class Teacher {
private Stu stu;
public Stu getStu() {
return stu;
}
public void setStu(Stu stu) {
this.stu = stu;
}
}
import com.zt.entity.Teacher;
import com.zt.entity.Stu;
import com.zt.entity.StuA;
public class TestNoDI {
public static void main(String[] args) {
Teacher teacher = new Teacher();
Stu stuA = new StuA();
teacher.setStu(stuA);
teacher.getStu().run();
}
}
Está tudo bem agora, mas e se o professor, em vez disso, der uma ordem ao aluno B? Vamos modificar a vinculação dos parâmetros:
import com.zt.entity.Teacher;
import com.zt.entity.Stu;
import com.zt.entity.StuB;
public class TestNoDI {
public static void main(String[] args) {
Teacher teacher = new Teacher();
Stu stuB = new StuB();
teacher.setStu(stuB);
teacher.getStu().run();
}
}
Uma vez que nosso sistema se torna muito grande, precisamos modificar todos esses lugares diretamente vinculados ao código! ! ! O Spring pode ser feito de uma vez por todas modificando-o uma vez no arquivo de configuração.
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id = "stuA" class = "com.zt.entity.StuA"/>
<bean id = "stuB" class = "com.zt.entity.StuB"/>
<bean id="teacher" class="com.zt.entity.Teacher">
<property name="stu" ref="stuA"/>
</bean>
</beans>
O ref da tag <property> é usado para apontar para o id do bean, que identifica qual classe de entidade deve ser atribuída como uma propriedade.
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zt.entity.Teacher;
public class TestHasDI {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans_experient.xml");
Teacher teacher = applicationContext.getBean("teacher", Teacher.class);
teacher.getStu().run();
}
}
Se quisermos modificar o material usado, podemos modificar o ref diretamente no arquivo de configuração sem modificar o código que usa este atributo:
<bean id="teacher" class="com.zt.entity.Teacher">
<property name="stu" ref="stuB"/>
</bean>
1. Injeção de construtor: chame o método de construção para injeção (deve ter o mesmo método de construção que o atributo de parâmetro e quantidade antes de poder ser usado)
A limitação do próprio Java torna impossível que dois métodos de construção tenham os mesmos atributos de parâmetro e número de parâmetros, garantindo assim a exclusividade de cada método de construção.
package com.zt.entity;
public class Dog {
private String name;
private int age;
private String master;
private String home;
public Dog() {
}
public Dog(String name, String master) {
this.name = name;
this.master = master;
}
public Dog(String name, int age, String master, String home) {
this.name = name;
this.age = age;
this.master = master;
this.home = home;
}
}
Chame a injeção de construção sem argumento:
<bean id="dog" class="com.zt.entity.Dog"/>
public class TestFirst {
@Test
public void testCreateBean(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
Dog dog = applicationContext.getBean("dog", Dog.class);
System.out.println(dog);
}
}
Chame a injeção de construção de parâmetro completo:
<bean id="dog" class="com.zt.entity.Dog">
<constructor-arg name="name" value="汪汪"/>
<constructor-arg name="home" value="nanjing"/>
<constructor-arg name="master" value="zjm"/>
<constructor-arg name="age" value="5"/>
</bean>
Pode-se ver que a ordem dos parâmetros é irrelevante.
Tente injetar usando um método de construção que não existe:
Você pode ver que as restrições do arquivo xml nos ajudaram a verificar a legitimidade do arquivo. Como não existe um método de construção com apenas um nome de String, ele não pode passar na verificação.
Para evitar erros de injeção, o Spring verifica estritamente os tipos de parâmetro, número de parâmetros e nomes de parâmetro.
A injeção de construtor também pode usar o índice para especificar atributos, começando em 0, o mesmo que a ordem dos parâmetros do construtor correspondente:
No entanto, o uso de índice é extremamente não recomendado, porque é fácil causar ambigüidade:
Obviamente, definimos os parâmetros de acordo com os dois métodos à direita, mas na verdade o Spring implementou o segundo. Para evitar essa situação, devemos usar o nome para vincular parâmetros e valores.
2. [Importante] Ao chamar a injeção de setter, diferentes tipos de métodos de injeção de propriedade:
<property> + value: Usado para injeção de tipos básicos, incluindo string além de tipos de dados básicos.
<property> + ref: Usado para injeção de tipo de referência.
<property> + <array> + <value>: Usado para injeção de tipo de array.
<property> + <list> + <value>: Usado para injeção de tipo de lista.
<property> + <map> + <entry>: Usado para injeção de tipo de mapa.
<property> + <props> + <prop>: usado para injeção de tipo de propriedade.
Você também pode injetar nulo em tipos de referência, usando a tag <null>.
Adicionamos uma classe: Endereço para experimentos
package com.zt.entity;
public class Adress {
}
package com.zt.entity;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Teacher {
private Stu stu;
private String name;
private Adress adress;
@Override
public String toString() {
return "Teacher{" +
"stu=" + stu +
", name='" + name + '\'' +
", adress=" + adress +
'}';
}
public Adress getAdress() {
return adress;
}
public void setAdress(Adress adress) {
this.adress = adress;
}
private String[] hobbies;
private List<String> duties;
private Map<String,String> family;
private Set<String> carts;
private Properties workExperience;
public Teacher() {
}
public Teacher(Stu stu, String name, String[] hobbies, List<String> duties, Map<String, String> family, Set<String> carts, Properties workExperience) {
this.stu = stu;
this.name = name;
this.hobbies = hobbies;
this.duties = duties;
this.family = family;
this.carts = carts;
this.workExperience = workExperience;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
public List<String> getDuties() {
return duties;
}
public void setDuties(List<String> duties) {
this.duties = duties;
}
public Map<String, String> getFamily() {
return family;
}
public void setFamily(Map<String, String> family) {
this.family = family;
}
public Set<String> getCarts() {
return carts;
}
public void setCarts(Set<String> carts) {
this.carts = carts;
}
public Properties getWorkExperience() {
return workExperience;
}
public void setWorkExperience(Properties workExperience) {
this.workExperience = workExperience;
}
public Stu getStu() {
return stu;
}
public void setStu(Stu stu) {
this.stu = stu;
}
}
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id = "stuA" class = "com.zt.entity.StuA"/>
<bean id = "stuB" class = "com.zt.entity.StuB"/>
<bean id="teacher" class="com.zt.entity.Teacher">
<!--注入基本属性-->
<property name="name" value="zzt"/>
<!--注入引用类型-->
<property name="stu" ref="stuB"/>
<!--注入null-->
<property name="adress">
<null/>
</property>
<!--注入数组-->
<property name="hobbies">
<array>
<value>羽毛球</value>
<value>橄榄球</value>
<value>排球</value>
</array>
</property>
<!--注入list-->
<property name="duties">
<list>
<value>猎头</value>
<value>顾问</value>
</list>
</property>
<!--注入map-->
<property name="family">
<map>
<entry key="husband" value="zjm"/>
</map>
</property>
<!--注入set-->
<property name="carts">
<set>
<value>衬衫</value>
<value>鞋子</value>
</set>
</property>
<!--注入property-->
<property name="workExperience">
<props>
<prop key="IT">项目经理</prop>
</props>
</property>
</bean>
</beans>
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zt.entity.Teacher;
public class TestHasDI {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans_experient.xml");
Teacher teacher = applicationContext.getBean("teacher", Teacher.class);
System.out.println(teacher);
}
}