【Primavera】Tópico de injeção

De acordo com o último tutorial da estrutura Spring do [Power Node], o primeiro conjunto de tutoriais Spring6 em toda a rede, segui Lao Du desde a primavera de aprendizado zero até o avançado e as notas originais de Lao Du https://www.yuque.com/ docs/share/866abad4-7106 -45e7-afcd-245a733b073f?# "Spring6" está organizado, senha do documento: mg9b


Os artigos relacionados à primavera são compilados e resumidos em: https://www.yuque.com/u27599042/zuisie


definir tópico de injeção

Injetar beans externos

  • Bean Externo: O bean a ser injetado é definido fora do bean que precisa ser injetado
  • Para beans externos, use o atributo ref na tag de propriedade para injeção, ou use a tag ref para injeção. A injeção através do atributo ref é comumente usada.
<!--声明/定义Bean-->
<bean id="orderDaoBean" class="com.powernode.spring6.dao.OrderDao"></bean>

<bean id="orderServiceBean" class="com.powernode.spring6.service.OrderService">
    <!--使用ref属性来引入外部Bean,这就是注入外部Bean-->
    <property name="orderDao" ref="orderDaoBean"/>
</bean>

Injetar beans internos

  • Bean Interno: Aninhe a tag do bean na tag do bean, ou seja, o bean que precisa ser injetado é declarado no bean que precisa ser injetado através da tag do bean, e então injetado diretamente no bean que precisa ser injetado.
<bean id="orderServiceBean2" class="com.powernode.spring6.service.OrderService">
    <property name="orderDao">
        <!--在property标签中使用嵌套的bean标签,这就是内部Bean-->
        <bean class="com.powernode.spring6.dao.OrderDao"></bean>
    </property>
</bean>

Injetar tipos simples

  • Se estiver atribuindo um valor a um tipo simples, ou seja, injetando um tipo simples em uma propriedade, use o atributo value ou a tag value em vez de ref.
public class User {
    
    
    private String username; // String是简单类型
    private String password;
    private int age; // int是简单类型

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public void setPassword(String password) {
    
    
        this.password = password;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                '}';
    }
}
<!--注入简单类型-->
<bean id="userBean" class="com.powernode.spring6.bean.User">
    <!--重点:如果是给简单类型赋值,就不能使用ref了。就需要使用value了。-->
    <property name="username" value="张三"/>
    <property name="password" value="123"/>
    <property name="age" value="20"/>
</bean>

Tipos simples no Spring

  • De acordo com a análise do código-fonte da classe BeanUtils, os tipos simples incluem:
    • tipo de dados básico
    • Classe de empacotamento correspondente ao tipo de dados básico
    • String ou outra subclasse CharSequence
    • Subclasse de número
    • Subclasse de data, java.util.Date é um tipo simples
    • Subclasse de enumeração
    • URI
    • URL
    • Subclasse temporal, Temporal é o tipo de horário e fuso horário fornecido pelo Java8
    • Locale, Locale é uma classe de linguagem e um tipo simples.
    • Aula
    • Além disso, os tipos de array correspondentes aos tipos de valor simples acima também estão incluídos.
public class BeanUtils{
    
    
    
    //.......
    
    /**
	 * Check if the given type represents a "simple" property: a simple value
	 * type or an array of simple value types.
	 * <p>See {@link #isSimpleValueType(Class)} for the definition of <em>simple
	 * value type</em>.
	 * <p>Used to determine properties to check for a "simple" dependency-check.
	 * @param type the type to check
	 * @return whether the given type represents a "simple" property
	 * @see org.springframework.beans.factory.support.RootBeanDefinition#DEPENDENCY_CHECK_SIMPLE
	 * @see org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#checkDependencies
	 * @see #isSimpleValueType(Class)
	 */
	public static boolean isSimpleProperty(Class<?> type) {
    
    
		Assert.notNull(type, "'type' must not be null");
		return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
	}

	/**
	 * Check if the given type represents a "simple" value type: a primitive or
	 * primitive wrapper, an enum, a String or other CharSequence, a Number, a
	 * Date, a Temporal, a URI, a URL, a Locale, or a Class.
	 * <p>{@code Void} and {@code void} are not considered simple value types.
	 * @param type the type to check
	 * @return whether the given type represents a "simple" value type
	 * @see #isSimpleProperty(Class)
	 */
	public static boolean isSimpleValueType(Class<?> type) {
    
    
		return (Void.class != type && void.class != type &&
				(ClassUtils.isPrimitiveOrWrapper(type) ||
				Enum.class.isAssignableFrom(type) ||
				CharSequence.class.isAssignableFrom(type) ||
				Number.class.isAssignableFrom(type) ||
				Date.class.isAssignableFrom(type) ||
				Temporal.class.isAssignableFrom(type) ||
				URI.class == type ||
				URL.class == type ||
				Locale.class == type ||
				Class.class == type));
	}
    
    //........
}

Teste todos os tipos simples

  • Escreva um programa que teste todos os tipos simples:
package com.powernode.spring6.beans;

import java.net.URI;
import java.net.URL;
import java.time.LocalDate;
import java.util.Date;
import java.util.Locale;

public class A {
    
    
    private byte b;
    private short s;
    private int i;
    private long l;
    private float f;
    private double d;
    private boolean flag;
    private char c;

    private Byte b1;
    private Short s1;
    private Integer i1;
    private Long l1;
    private Float f1;
    private Double d1;
    private Boolean flag1;
    private Character c1;

    private String str;

    private Date date;

    private Season season;

    private URI uri;

    private URL url;

    private LocalDate localDate;

    private Locale locale;

    private Class clazz;
    
    // 生成setter方法
    // 生成toString方法
}

enum Season {
    
    
    SPRING, SUMMER, AUTUMN, WINTER
}
  • você precisa estar ciente é:
    • Se Date for considerado um tipo simples, o formato da string de data não pode ser escrito casualmente. O formato deve estar em conformidade com o formato do método toString() de Date. Obviamente, isso é de mau gosto. Se fornecermos uma string de data como esta: 11/10/2010, ela não poderá ser atribuída a um atributo do tipo Data.
    • Após o spring6, quando uma URL é injetada, a validade da string da URL será verificada. Se for um URL existente, tudo bem. Relata um erro se ele não existir.

Caso clássico de injeção de tipos simples

  • Caso clássico: injetar valores em atributos da fonte de dados:
  • Suponha que agora queiramos escrever uma fonte de dados à mão. Todos sabemos que todas as fontes de dados devem implementar a interface javax.sql.DataSource, e a fonte de dados deve ter informações para se conectar ao banco de dados, como: driver, url, nome de usuário , senha, etc.
  • Fonte de dados: todas as fontes de dados podem fornecer objetos Connection.
/**
 * 所有的数据源都要实现java规范:javax.sql.DataSource
 **/
public class MyDataSource implements DataSource {
    
     // 可以把数据源交给Spring容器来管理。

    private String driver;
    private String url;
    private String username;
    private String password;

    public void setDriver(String driver) {
    
    
        this.driver = driver;
    }

    public void setUrl(String url) {
    
    
        this.url = url;
    }

    public void setUsername(String username) {
    
    
        this.username = username;
    }

    public void setPassword(String password) {
    
    
        this.password = password;
    }

    @Override
    public String toString() {
    
    
        return "MyDataSource{" +
                "driver='" + driver + '\'' +
                ", url='" + url + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public Connection getConnection() throws SQLException {
    
    
        // 获取数据库连接对象的时候需要4个信息:driver url username password
        return null;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
    
    
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
    
    
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {
    
    

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {
    
    

    }

    @Override
    public int getLoginTimeout() throws SQLException {
    
    
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
    
    
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
    
    
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
    
    
        return false;
    }
}
<!--让spring来管理我们的数据源-->
<bean id="myDataSource" class="com.powernode.spring6.jdbc.MyDataSource">
    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/spring6"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
</bean>
@Test
public void testDataSource(){
    
    
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-datasource.xml");
    MyDataSource dataSource = applicationContext.getBean("dataSource", MyDataSource.class);
    System.out.println(dataSource);
}

Atribuição de propriedade em cascata

// 班级类
public class Clazz {
    
    
    // 班级名称
    private String name;

    public void setName(String name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Clazz{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class Student {
    
    
    private String name;

    // 学生属于哪个班级
    private Clazz clazz;

    public void setClazz(Clazz clazz) {
    
    
        this.clazz = clazz;
    }

    // 使用级联属性赋值,这个需要这个get方法。
    // 因为级联给学生所在的班级属性赋值会调用学生的getClazz()方法
    public Clazz getClazz() {
    
    
        return clazz;
    }

    public void setName(String name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Student{" +
                "name='" + name + '\'' +
                ", clazz=" + clazz +
                '}';
    }
}
  • Método de injeção original
<bean id="studentBean" class="com.powernode.spring6.bean.Student">
    <!--简单类型,使用value-->
    <property name="name" value="张三"/>
    <!--这不是简单类型,使用ref-->
    <property name="clazz" ref="clazzBean"/>
</bean>

<bean id="clazzBean" class="com.powernode.spring6.bean.Clazz">
    <property name="name" value="高三一班"/>
</bean>
  • Injeção em cascata:
  • Nota: Para atribuição de atributos em cascata, o método get deve ser fornecido para variáveis ​​de membro que fazem referência a outros objetos, porque ao executar a atribuição de atributos em cascata, você precisa primeiro chamar o método get para obter as variáveis ​​de membro que fazem referência a outros objetos e, em seguida, chamar o variável de membro.Método de conjunto de atributos para atribuição de atributos
<!--使用级联属性赋值需要注意两点:
        1. 配置的顺序不能颠倒,必须如下顺序。
        2. clazz属性必须提供getter方法。
-->
<bean id="studentBean" class="com.powernode.spring6.bean.Student">
    <!--简单类型,使用value-->
    <property name="name" value="张三"/>
    <!--这不是简单类型,使用ref-->
		<!-- 因为后面要对该对象的属性赋值,所以必须先有该对象 -->
    <property name="clazz" ref="clazzBean"/>
    <!--级联属性赋值-->
    <!-- name="clazz.name" 会调用学生的getClazz()方法,
  			所以学生类必须提供getClazz()方法,然后调用set方法给班级的name赋值 
  	-->
    <property name="clazz.name" value="高三二班"/>
</bean>

<!-- 这里不进行注入 -->
<bean id="clazzBean" class="com.powernode.spring6.bean.Clazz"></bean>

Injetar na matriz

Os elementos da matriz são tipos simples

public class QianDaYe {
    
    
    private String[] aiHaos;

    public void setAiHaos(String[] aiHaos) {
    
    
        this.aiHaos = aiHaos;
    }

    @Override
    public String toString() {
    
    
        return "QianDaYe{" +
                "aiHaos=" + Arrays.toString(aiHaos) +
                '}';
    }
}
<bean id="yuQian" class="com.powernode.spring6.bean.QianDaYe">

    <!-- 这个数组属性当中的元素类型是String,是简单类型 -->
    <property name="aiHaos">
        <array>
            <value>抽烟</value>
            <value>喝酒</value>
            <value>烫头</value>
        </array>
    </property>

</bean>

Os elementos da matriz são do tipo não simples

public class Woman {
    
    
    private String name;

    public void setName(String name) {
    
    
        this.name = name;
    }

    @Override
    public String toString() {
    
    
        return "Woman{" +
                "name='" + name + '\'' +
                '}';
    }
}
public class QianDaYe {
    
    
    private String[] aiHaos;

    // 多个女性朋友
    private Woman[] womens;

    public void setWomens(Woman[] womens) {
    
    
        this.womens = womens;
    }

    public void setAiHaos(String[] aiHaos) {
    
    
        this.aiHaos = aiHaos;
    }

    @Override
    public String toString() {
    
    
        return "QianDaYe{" +
                "aiHaos=" + Arrays.toString(aiHaos) +
                ", womens=" + Arrays.toString(womens) +
                '}';
    }
}
<bean id="w1" class="com.powernode.spring6.bean.Woman">
    <property name="name" value="小花"/>
</bean>

<bean id="w2" class="com.powernode.spring6.bean.Woman">
    <property name="name" value="小亮"/>
</bean>

<bean id="w3" class="com.powernode.spring6.bean.Woman">
    <property name="name" value="小明"/>
</bean>

<bean id="yuQian" class="com.powernode.spring6.bean.QianDaYe">

    <!-- 这个数组属性当中的元素类型是String简单类型 -->
    <property name="aiHaos">
        <array>
            <value>抽烟</value>
            <value>喝酒</value>
            <value>烫头</value>
        </array>
    </property>

    <!-- 这个数组当中的类型就不是简单类型了-->
    <property name="womens">
        <array>
            <ref bean="w1"/>
            <ref bean="w2"/>
            <ref bean="w3"/>
        </array>
    </property>

</bean>

Resumo da injeção de arrays

  • Se a matriz contiver tipos simples, use a tag value.
  • Se a matriz contiver tipos não simples, use a tag ref.

Coleção de lista de injeção e coleção de conjunto

  • Coleção de listas: ordenada e repetível
    • Nota: Use a tag list ao injetar na coleção List. Se a coleção List for do tipo simples, use a tag value. Caso contrário, use a tag ref.
  • Coleção de conjuntos: não ordenada e não repetível
    • Pontos principais: Use tags ao injetar coleções de conjuntos <set>. Se os elementos na coleção de conjuntos forem de tipos simples, use a tag value. Caso contrário, use a tag ref.
public class Person {
    
    

    // 注入List集合
    private List<String> names;

    // 注入Set集合
    private Set<String> addrs;

    public void setNames(List<String> names) {
    
    
        this.names = names;
    }

    public void setAddrs(Set<String> addrs) {
    
    
        this.addrs = addrs;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "names=" + names +
                ", addrs=" + addrs +
                '}';
    }
}
<bean id="personBean" class="com.powernode.spring6.bean.Person">

    <property name="names">
        <!--list集合有序可重复-->
        <list>
            <value>张三</value>
            <value>李四</value>
            <value>王五</value>
            <value>张三</value>
            <value>张三</value>
            <value>张三</value>
            <value>张三</value>
        </list>
    </property>

    <property name="addrs">
        <!--set集合无序不可重复-->
        <set>
            <value>北京大兴区</value>
            <value>北京大兴区</value>
            <value>北京海淀区</value>
            <value>北京海淀区</value>
            <value>北京大兴区</value>
        </set>
    </property>
</bean>

Injetar coleção de mapas e injetar propriedades

  • Coleção de mapas:
    • Usar <map>tags
    • Se a chave for de um tipo simples, use o atributo key, caso contrário, use o atributo key-ref.
    • Se value for um tipo simples, use o atributo value, caso contrário, use o atributo value-ref.
  • java.util.Properties herda java.util.Hashtable, então Properties também é uma coleção de mapas.
    • As propriedades são feitas usando <props>tags aninhadas dentro <prop>de tags.
    • Em Propriedades, os tipos chave e valor são ambos tipos String.
public class Person {
    
    

    // 注入Map集合
    // 多个电话
    private Map<Integer, String> phones;

    // 注入属性类对象
    // Properties本质上也是一个Map集合。
    // Properties的父类Hashtable,Hashtable实现了Map接口。
    // 虽然这个也是一个Map集合,但是和Map的注入方式有点像,但是不同。
    // Properties的key和value只能是String类型。
    private Properties properties;

    public void setProperties(Properties properties) {
    
    
        this.properties = properties;
    }

    public void setPhones(Map<Integer, String> phones) {
    
    
        this.phones = phones;
    }

    @Override
    public String toString() {
    
    
        return "Person{" +
                "phones=" + phones +
                ", properties=" + properties +
                '}';
    }
}
<bean id="personBean" class="com.powernode.spring6.bean.Person">
    
    <property name="properties">
        <!--注入Properties属性类对象-->
        <props>
            <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
            <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
            <prop key="username">root</prop>
            <prop key="password">123456</prop>
        </props>
    </property>

    <property name="phones">
        <!--注入Map集合-->
        <map>
            <!--如果key和value不是简单类型就用这个配置。-->
            <!--<entry key-ref="" value-ref=""/>-->
            <!--如果是简单类型就是key和value-->
            <entry key="1" value="110"/>
            <entry key="2" value="120"/>
            <entry key="3" value="119"/>
        </map>
    </property>
</bean>

Injetar strings nulas e vazias

  • Para injetar uma string vazia use: <value/>ou value=""
  • Injete nulo usando: <null/>ou não atribua um valor à propriedade
public class Cat {
    
    
    private String name;
    private int age;

    public void setName(String name) {
    
    
        this.name = name;
    }

    public String getName() {
    
    
        return name;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    @Override
    public String toString() {
    
    
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
<bean id="catBean" class="com.powernode.spring6.bean.Cat">
    <!--不给属性注入,属性的默认值就是null-->
    <!--<property name="name" value="tom"></property>-->
    <!-- 这不是注入null,这只是注入了一个"null"字符串-->
    <!--<property name="name" value="null"/>-->
    <!--这种方式是手动注入null-->
    <!--<property name="name">
        <null/>
    </property>-->

    <!--注入空字符串第一种方式-->
    <!--<property name="name" value=""/>-->
    <!--注入空字符串第二种方式-->
    <property name="name">
        <value/>
    </property>

    <property name="age" value="3"></property>
</bean>

O valor injetado contém símbolos especiais

  • Existem 5 caracteres especiais em XML, a saber: <, >, ', ", &
  • Os cinco símbolos especiais acima serão tratados especialmente em XML e serão analisados ​​como parte da sintaxe XML.Se estes símbolos especiais aparecerem directamente na string injectada,será reportado um erro.
  • Existem duas soluções:
    • Tipo 1: Use caracteres de escape para substituir símbolos especiais.
    • O segundo tipo: coloque a string contendo símbolos especiais em <![CDATA[]]>:. Os dados colocados em uma seção CDATA não serão analisados ​​por um analisador de arquivo XML. Ao usar CDATA, você não pode usar o atributo value, apenas a tag value.
  • Os caracteres de escape correspondentes aos 5 caracteres especiais são:
public class MathBean {
    
    
    private String result;

    public void setResult(String result) {
    
    
        this.result = result;
    }

    @Override
    public String toString() {
    
    
        return "MathBean{" +
                "result='" + result + '\'' +
                '}';
    }
}
    <bean id="mathBean" class="com.powernode.spring6.bean.MathBean">
        <!--第一种方案:使用实体符号代替特殊符号-->
        <!--<property name="result" value="2 &lt; 3" />-->

        <!--第二种方案:使用<![CDATA[]]>-->
        <property name="result">
            <!--只能使用value标签-->
            <value><![CDATA[2 < 3]]></value>
        </property>

    </bean>

injeção de namespace p

  • Objetivo: Simplificar a configuração.
  • O namespace p é na verdade uma simplificação da injeção de conjunto.
  • Os pré-requisitos para usar a injeção de namespace p incluem dois:
    • Primeiro: adicione as informações de configuração do namespace p nas informações do cabeçalho XML:xmlns:p="http://www.springframework.org/schema/p"
    • Segundo: a injeção de namespace p é baseada no método setter, portanto, o atributo correspondente precisa fornecer um método setter.
public class Dog {
    
    
    // 简单类型
    private String name;
    private int age;
    // 非简单类型
    private Date birth;

    // p命名空间注入底层还是set注入,只不过p命名空间注入可以让spring配置变的更加简单。
    public void setName(String name) {
    
    
        this.name = name;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }

    public void setBirth(Date birth) {
    
    
        this.birth = birth;
    }

    @Override
    public String toString() {
    
    
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birth=" + birth +
                '}';
    }
}
<?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.xsd">

    <!--
        第一步:在spring的配置文件头部添加p命名空间。
  					xmlns:p="http://www.springframework.org/schema/p"
        第二步:使用 p:属性名 = "属性值"
    -->
    <bean id="dogBean" class="com.powernode.spring6.bean.Dog" p:name="小花" p:age="3" p:birth-ref="birthBean"/>

    <!--这里获取的是当前系统时间。-->
    <bean id="birthBean" class="java.util.Date"/>

</beans>

c injeção de namespace

  • O namespace c é injetado pelo construtor simplificado.
  • Dois pré-requisitos para usar o namespace c:
    • Primeiro: as informações de configuração do namespace c precisam ser adicionadas ao cabeçalho do arquivo de configuração xml:xmlns:c="http://www.springframework.org/schema/c"
    • Segundo: métodos de construção precisam ser fornecidos.
  • O namespace c depende do construtor.
  • Nota: Independentemente do namespace p ou do namespace c, tipos simples e tipos não simples podem ser injetados durante a injeção.
public class People {
    
    
    private String name;
    private int age;
    private boolean sex;

    // c命名空间是简化构造注入的。
    // c命名空间注入办法是基于构造方法的。
    public People(String name, int age, boolean sex) {
    
    
        this.name = name;
        this.age = age;
        this.sex = sex;
    }

    @Override
    public String toString() {
    
    
        return "People{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                '}';
    }
}
<?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:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--
        第一步:在spring的配置文件头部添加: 
  					xmlns:c="http://www.springframework.org/schema/c"
        第二步:使用
            c:_0 下标方式
            c:name 参数名方式
    -->
    <!--<bean id="peopleBean" class="com.powernode.spring6.bean.People" c:_0="zhangsan" c:_1="30" c:_2="true"></bean>-->
    <bean id="peopleBean" class="com.powernode.spring6.bean.People" c:name="jack" c:age="30" c:sex="true"></bean>

</beans>

namespace do utilitário

  • Usar o namespace util permite a reutilização da configuração.
  • O pré-requisito para usar o namespace util é adicionar informações de configuração ao cabeçalho do arquivo de configuração do Spring.
  • do seguinte modo:
<?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:util="http://www.springframework.org/schema/util"
  
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           
  												 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
package com.powernode.spring6.beans;

import java.util.Properties;

public class MyDataSource1 {
    
    
	// Properties属性类对象,这是一个Map集合,
    // key和value都是String类型。
    private Properties properties;

    public void setProperties(Properties properties) {
    
    
        this.properties = properties;
    }

    @Override
    public String toString() {
    
    
        return "MyDataSource1{" +
                "properties=" + properties +
                '}';
    }
}
package com.powernode.spring6.beans;

import java.util.Properties;

public class MyDataSource2 {
    
    
    private Properties properties;

    public void setProperties(Properties properties) {
    
    
        this.properties = properties;
    }

    @Override
    public String toString() {
    
    
        return "MyDataSource2{" +
                "properties=" + properties +
                '}';
    }
}
<?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:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <!--引入util命名空间
        在spring的配置文件头部添加:
        		xmlns:util="http://www.springframework.org/schema/util"
		        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
    -->
    <util:properties id="prop">
        <prop key="driver">com.mysql.cj.jdbc.Driver</prop>
        <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
        <prop key="username">root</prop>
        <prop key="password">123</prop>
    </util:properties>

    <!--数据源1-->
    <bean id="ds1" class="com.powernode.spring6.jdbc.MyDataSource1">
        <property name="properties" ref="prop"/>
    </bean>

    <!--数据源2-->
    <bean id="ds2" class="com.powernode.spring6.jdbc.MyDataSource2">
        <property name="properties" ref="prop"/>
    </bean>

</beans>

Autowiring baseado em XML

  • A mola também pode completar a injeção automatizada, também chamada de montagem automática.
  • Ele pode ser montado automaticamente com base no nome ou montado automaticamente com base no tipo.

Monte automaticamente com base no nome

  • Se montado com base no nome (byName), a camada inferior chamará o método set para injeção.
  • Por exemplo: o nome correspondente de setAge() é idade, o nome correspondente de setPassword() é senha e o nome correspondente de setEmail() é email.
public class OrderDao {
    
    

    private static final Logger logger = LoggerFactory.getLogger(OrderDao.class);

    public void insert(){
    
    
        logger.info("订单正在生成....");
    }
}
public class OrderService {
    
    

    private OrderDao orderDao;

    // 通过set方法给属性赋值。
    public void setOrderDao(OrderDao orderDao) {
    
    
        this.orderDao = orderDao;
    }

    /**
     * 生成订单的业务方法。。。
     */
    public void generate(){
    
    
        orderDao.insert();
    }
}
<!--根据名字进行自动装配-->
<!--注意:自动装配也是基于set方式实现的。-->
<bean id="orderService" class="com.powernode.spring6.service.OrderService" autowire="byName"></bean>

<!--id一般也叫作bean的名称。-->
<!--根据名字进行自动装配的时候,被注入的对象的bean的id不能随便写,
		set方法的方法名去掉set,剩下单词首字母小写。-->
<bean id="orderDao" class="com.powernode.spring6.dao.OrderDao"/>
  • Autowire="byName" precisa ser adicionado ao Bean OrderService, o que significa montagem automática por nome.
  • Existe um atributo OrderDao na classe OrderService, e o nome do atributo OrderDao é orderDao, e o método set correspondente é setOrderDao(), que é exatamente igual ao id do Bean OrderDao e pode ser montado automaticamente de acordo com o nome.

Montagem automática baseada no tipo

  • Seja byName ou byType, eles são baseados no método set durante a montagem, portanto, o método set deve ser fornecido e não é possível fornecer um método construtor.
  • Se byType, ao montar por tipo, houver dois beans do mesmo tipo no arquivo de configuração, será reportado um erro.
  • Quando byType realiza montagem automática, um determinado tipo de Bean no arquivo de configuração deve ser único e não pode aparecer como múltiplo.
    • Se houver vários beans do mesmo tipo, o Spring não saberá qual bean usar para injeção.
public class CustomerService {
    
    

    private UserDao userDao;
    private VipDao vipDao;

    public void setUserDao(UserDao userDao) {
    
    
        this.userDao = userDao;
    }

    public void setVipDao(VipDao vipDao) {
    
    
        this.vipDao = vipDao;
    }

    public void save(){
    
    
        userDao.insert();
        vipDao.insert();
    }

}
    <!--根据类型进行自动装配-->
    <!--自动装配是基于set方法的-->
    <!--根据类型进行自动装配的时候,在有效的配置文件当中,某种类型的实例只能有一个。-->
    <bean class="com.powernode.spring6.dao.VipDao"></bean>
    <bean id="x" class="com.powernode.spring6.dao.UserDao"></bean>
    <!--如果byType,根据类型装配时,如果配置文件中有两个类型一样的bean会报错-->
    <!--<bean id="y" class="com.powernode.spring6.dao.UserDao"></bean>-->
    <bean id="cs" class="com.powernode.spring6.service.CustomerService" autowire="byType"></bean>

Spring introduz arquivos de configuração de propriedades externas

  • Todos sabemos que ao escrever uma fonte de dados, precisamos de informações para nos conectarmos ao banco de dados, como: url do driver, nome de usuário, senha e outras informações. Essas informações podem ser gravadas separadamente em um arquivo de configuração de propriedades, para que seja mais conveniente para os usuários modificá-las?
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring6
jdbc.username=root
jdbc.password=123
<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!--
        引入外部的properties文件
        第一步:引入context命名空间。
          xmlns:context="http://www.springframework.org/schema/context"
          http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
        第二步:使用标签context:property-placeholder的location属性来指定属性配置文件的路径。
                    location默认从类的根路径下开始加载资源。
    -->
    <context:property-placeholder location="jdbc.properties"/>

    <!--配置数据源-->
    <bean id="ds" class="com.powernode.spring6.jdbc.MyDataSource">
        <!--怎么取值呢?第三步:${key}-->
        <property name="driver" value="${jdbc.driverClass}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <!--加前缀是由于spring加载变量是优先从系统变量中进行加载,username系统变量已经存在-->
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

</beans>

Acho que você gosta

Origin blog.csdn.net/m0_53022813/article/details/132057743
Recomendado
Clasificación