Notas de estudo da primavera-01 uso simples + inversão de controle

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);
    }
}

 

 

Acho que você gosta

Origin blog.csdn.net/qq_39304630/article/details/112345926
Recomendado
Clasificación