【Spring6】| Spring's implementation of IoC (core focus)

Table of contents

One: Spring's implementation of IoC

1. IoC Inversion of Control

2. Dependency Injection

2.1 set injection

2.2 Construct injection

3. Set injection topic

3.1 Injecting external beans

3.2 Injecting internal beans

3.3 Injecting Simple Types

3.4 Cascade attribute assignment (understand)

3.5 Injecting arrays

3.6 Inject List collection and Set collection

3.7 Inject Map and Properties collections

3.8 Injecting null and empty strings

3.9 The injected value contains special symbols

4. p namespace injection

5. C namespace injection

6. util namespace

7. XML-based autowiring (byName & byType)

7.1 Automatic assembly according to name (byName)

7.2 Automatic assembly according to type (byType)

8. Spring introduces external attribute configuration files (using the context namespace)


One: Spring's implementation of IoC

We have learned how to create management objects with spring, and then we need to learn how to create relationships between objects and use dependency injection!

1. IoC Inversion of Control

(1) Inversion of control is an idea, a new design pattern!

(2) The purpose of inversion of control is to reduce the degree of program coupling, improve program scalability, achieve the OCP principle, and achieve the DIP principle.

(3) Inversion of control, what is the inversion?

Hand over the creation right of the object to the third-party container.

The right to maintain the relationship between objects and objects is handed over to the third-party container.

(4) How to implement the idea of ​​inversion of control ?

DI (Dependency Injection): dependency injection

2. Dependency Injection

Dependency injection implements the idea of ​​inversion of control!

Spring completes Bean management through dependency injection. Bean management refers to: the creation of Bean objects, and the assignment of attributes in Bean objects (or the maintenance of relationships between Bean objects).

Dependency injection:

  • Dependency refers to the relationship between objects and objects.
  • Injection refers to a data transfer behavior, through the injection behavior to make objects and objects have a relationship.

There are two common implementations of dependency injection:

  • The first type: set injection
  • The second type: construct injection

2.1 set injection

Set injection is implemented based on the set method. The bottom layer will call the set method corresponding to the attribute through the reflection mechanism and then assign a value to the attribute; this method requires the attribute to provide a set method to the outside world !

pom.xml configuration

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bjpowernode</groupId>
    <artifactId>spring6-002-dependency-injection</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <!--配置多个仓库-->
    <repositories>
        <!--spring6里程碑的仓库-->
        <repository>
            <id>repository.spring.milestone</id>
            <name>Spring Milestone Repository</name>
            <url>https://repo.spring.io/milestone</url>
        </repository>
    </repositories>

    <dependencies>
        <!--spring context依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.0-M2</version>
        </dependency>
        <!--单元测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--log4j2的依赖-->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.19.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j2-impl</artifactId>
            <version>2.19.0</version>
        </dependency>
    </dependencies>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
    </properties>

</project>

log4j2.xml log configuration

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <loggers>
        <root level="DEBUG">
            <appender-ref ref="spring6log"/>
        </root>
    </loggers>

    <appenders>
        <console name="spring6log" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/>
        </console>
    </appenders>

</configuration>

UserDao class: the operation of connecting to the database

package com.bjpowernode.spring6.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserDao {
    // 一般声明为常量
   private static final Logger logger = LoggerFactory.getLogger(UserDao.class);
    // 使用日志进行打印,用System.out.println也可以
    public void insert(){
        logger.info("数据库正在保存用户信息!");
    }
}

UserService class: call the method in UserDao

①For set injection, a set method must be provided; the Spring container will call this set method to assign a value to the userDao attribute.

②This set method does not conform to the javabean specification, but it must start with set, for example: setUD is also possible; here I am using the javabean specification automatically generated by IDEA.

package com.bjpowernode.spring6.service;

import com.bjpowernode.spring6.dao.UserDao;

public class UserService {
    private UserDao userDao;

    // set注入,必须提供一个set方法
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void saveUser(){
        // 调用UserDao保存用户信息
        userDao.insert();
    }
}

spring.xml configuration

① Configure userDaoBean and UserService to let spring manage these two classes.

② For UserService, if you want Spring to call the corresponding set method, you need to configure the property tag :

name attribute value: the method name of the set method, remove the set, and then lowercase the first letter of the remaining word
ref attribute value: translated as a reference, the English word references, followed by the id of the bean to be injected

<?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 https://www.springframework.org/schema/util/spring-util.xsd">

     <!--配置dao-->
    <bean id="userDaoBean" class="com.bjpowernode.spring6.dao.UserDao"/>
     <!--配置service-->
    <bean id="userServiceBean" class="com.bjpowernode.spring6.service.UserService">
        <property name="userDao" ref="userDaoBean" />
    </bean>
</beans>

③In addition, for the property tag, the ref attribute can also use the label method , but the use of the ref attribute is the majority:

<bean id="userServiceBean" class="com.powernode.spring6.service.UserService">
  <property name="userDao">
    <ref bean="userDaoBean"/>
  </property>
</bean>

write test class

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.service.UserService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DITest {
    @Test
    public void testSetDI(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        UserService userServiceBean = applicationContext.getBean("userServiceBean", UserService.class);
        userServiceBean.saveUser();
    }
}

Results of the:

The log information is output normally, indicating two problems:

① spring creates UserDao and UserService objects normally!

②spring associates the relationship between objects and objects!

Summary: The core implementation principle of set injection is to assign values ​​to attributes by calling the set method through the reflection mechanism, so that a relationship can be created between two objects.

2.2 Construct injection

Core principle: Assign values ​​to properties by calling constructors .

①set injection: the object is created first before the set method can be executed to assign values ​​to the properties.

②Constructive injection: it is to assign values ​​to attributes while creating objects, and the timing is different.

When defining a VipDao class

package com.bjpowernode.spring6.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class VipDao {
    private static final Logger logger = LoggerFactory.getLogger(VipDao.class);
    public void delete(){
        logger.info("正在删除信息!");
    }
}

ConstructService类

Constructor injection must provide a constructor!

package com.bjpowernode.spring6.service;

import com.bjpowernode.spring6.dao.UserDao;
import com.bjpowernode.spring6.dao.VipDao;

public class ConstructService {
    private UserDao userDao;
    private VipDao vipDao;

    // 构造注入,必须有构造方法
    public ConstructService(UserDao userDao, VipDao vipDao) {
        this.userDao = userDao;
        this.vipDao = vipDao;
    }
    
    public void save(){
        userDao.insert();
        vipDao.delete();
    }
}

bean.xml configuration

There are three ways to access: using the constructor-arg tag

① The first method is based on the subscript index method, and the order of the subscripts is the order of the parameters of the construction method.

②The second method is based on the name of the constructor parameter name .

③The third way is to inject according to the type, if not specified, spring will infer the type matching by itself .

<?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.xsd">

     <bean id="userDaoBean" class="com.bjpowernode.spring6.dao.UserDao"/>
     <bean id="vipDaoBean" class="com.bjpowernode.spring6.dao.VipDao"/>
     <bean id="constructServiceBean" class="com.bjpowernode.spring6.service.ConstructService">
         <!--第一种方式-->
          <constructor-arg index="0" ref="userDaoBean"/>
          <constructor-arg index="1" ref="vipDaoBean" />
          <!--第二种方式-->
          <constructor-arg name="userDao" ref="userDaoBean"/>
          <constructor-arg name="vipDao" ref="vipDaoBean"/>
          <!--第三种方式-->
          <constructor-arg ref="userDaoBean"/>
          <constructor-arg ref="vipDaoBean" />
     </bean>

</beans>

write tests

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.service.ConstructService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ConstructTest {
    @Test
    public void testConstructDI(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
        ConstructService constructServiceBean = applicationContext.getBean("constructServiceBean", ConstructService.class);
        constructServiceBean.save();
    }
}

Results of the:

3. Set injection topic

In set injection and construction injection, set injection is used more, so let's learn about the topic of set injection!

3.1 Injecting external beans

(1) The case we used before has always been the way of injecting external beans!

(2) Features of external beans : The bean is defined outside, and injected using the ref attribute in the property tag ; usually this method is commonly used!

<?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 https://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="userDaoBean" class="com.bjpowernode.spring6.dao.UserDao"/>
    <bean id="userServiceBean" class="com.bjpowernode.spring6.service.UserService">
        <property name="userDao" ref="userDaoBean" />
    </bean>
</beans>

3.2 Injecting internal beans

The way of internal beans : directly nest bean tags in bean tags, and do not need to introduce ref attributes .

<?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 https://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="userServiceBean" class="com.bjpowernode.spring6.service.UserService">
        <property name="userDao">
            <bean class="com.bjpowernode.spring6.dao.UserDao"/>
        </property>
    </bean>
</beans>

3.3 Injecting Simple Types

(1) When injecting before, the properties of the object are all other objects; what if the properties of the object are of type int? You can also assign a value to the attribute through set injection. In fact, as long as you can call the set method, you can assign a value to the attribute .

(2) Key point: If you assign a value to a simple type , you cannot use the ref attribute, you need to use the value attribute !

User class: two simple types are defined, and the set method is written

package com.bjpowernode.spring6.bean;

public class User {
    private String name;
    private int age;

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

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

set-di.xm configuration

Note: You can use either the value tag or the value attribute (commonly used)

<?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.xsd">

    <bean id="userBean" class="com.bjpowernode.spring6.bean.User">
        <property name="age" value="18"/>
        <property name="name" value="张三"/>
    </bean>
</beans>

write tests

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.bean.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SetDITest {
    @Test
    public void testSimpleTypeSet(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("set-di.xml");
        User user = applicationContext.getBean("userBean", User.class);
        System.out.println(user);
    }
}

Execution result: the toString method will be called by default

Special attention needs to be paid: if assigning a value to a simple type, use the value attribute or value tag instead of ref!

(3) So what are the simple types? You can analyze it through Spring's source code!

Double-click shift to search for the BeanUtils class , and ctrl+F12 to search for the isSimpleValueType method, which contains simple types:

(4) Here we focus on the Date type. If you insist on treating the Date type as a simple type and using value assignment, the format of this date has requirements: Thu Jan 12 21:05:49 CST 2023 , so in actual development, We generally use the ref attribute to assign values ​​to Date type attributes!

(5) A classic case of simple type injection: inject values ​​into the properties of the data source:

Suppose we now want to write a data source by ourselves (that can provide Connection objects), we all know that all data sources must implement the javax.sql.DataSource interface, and the data source should have information about connecting to the database, such as: driver, url , username, password, etc.

Data source MyDataSource

package com.bjpowernode.spring6.jdbc;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

public class MyDateSource implements DataSource {
    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 "MyDateSource{" +
                "driver='" + driver + '\'' +
                ", url='" + url + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public Connection getConnection() throws SQLException {
        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-datasource.xml: Use spring's dependency injection to complete the creation of data source objects and the assignment of attributes

<?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.xsd">
        
    <bean name="myDataSource" class="com.bjpowernode.spring6.jdbc.MyDateSource">
        <property name="driver" value="com.mysql.jdbc.driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/spring6"/>
        <property name="username" value="root"/>
        <property name="password" value="123"/>
    </bean>
</beans>

write tests

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.bean.User;
import com.bjpowernode.spring6.jdbc.MyDateSource;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SetDITest {
    @Test
    public void testMyDataSource(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-datasource.xml");
        MyDateSource myDataSource = applicationContext.getBean("myDataSource", MyDateSource.class);
        System.out.println(myDataSource);
    }

}

 Test result: Successfully injected information to connect to the database

3.4 Cascade attribute assignment (understand)

Let's first review the original injection method, and then use cascading attribute assignment for comparison!

clazz class class

package com.bjpowernode.spring6.bean;

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

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

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

Student class

package com.bjpowernode.spring6.bean;

public class Student {
    // 学生姓名
    private String name;
    // 班级
    private Clazz clazz;

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

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

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", clazz=" + clazz +
                '}';
    }
}

The first method: the original injection method

<?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.xsd">


    <bean name="clazzBean" class="com.bjpowernode.spring6.bean.Clazz">
        <property name="name" value="高三一班"/>
    </bean>
    <bean name="studentBean" class="com.bjpowernode.spring6.bean.Student">
        <property name="name" value="张三"/>
        <property name="clazz" ref="clazzBean"/>
    </bean>
</beans>

The second method: cascading injection method

There are two points to note when using cascading property assignments:

①The order of configuration cannot be reversed, first configure student and then configure clazz

The clazz attribute must provide the getClazz() method (so the getter method must be added to the Student class)

<?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.xsd">

    <bean name="studentBean" class="com.bjpowernode.spring6.bean.Student">
        <property name="name" value="张三"/>
        <property name="clazz" ref="clazzBean"/>
        <!--级联属性赋值-->
        <property name="clazz.name" value="高三一班"/>
    </bean>
    <bean name="clazzBean" class="com.bjpowernode.spring6.bean.Clazz" />
</beans>

Results of the:

3.5 Injecting arrays

There are two main situations to learn here: when the elements in the array are simple types and when the elements in the array are non- simple types !

class Woman, as a non-simple type

package com.bjpowernode.spring6.bean;

public class Woman {
    private String name;

    @Override
    public String toString() {
        return "Woman{" +
                "name='" + name + '\'' +
                '}';
    }

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

QY class, which contains array properties of simple types and non-simple types

package com.bjpowernode.spring6.bean;

import java.util.Arrays;

public class QY {
    // 简单类型的数组
    private String[] loves;
    // 非简单类型的数组
    private Woman[] women;

    @Override
    public String toString() {
        return "QY{" +
                "loves=" + Arrays.toString(loves) +
                ", women=" + Arrays.toString(women) +
                '}';
    }

    public void setLoves(String[] loves) {
        this.loves = loves;
    }

    public void setWomen(Woman[] women) {
        this.women = women;
    }
}

spring-array.xml configuration

When the attribute is an array, you need to use the array tag first, and then write the value and ref tags in the array tag for assignment!

<?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.xsd">
    <!--准备好非简单类型数据-->
    <bean id="w1" class="com.bjpowernode.spring6.bean.Woman">
        <property name="name" value="小花"/>
    </bean>
    <bean id="w2" class="com.bjpowernode.spring6.bean.Woman">
        <property name="name" value="小红"/>
    </bean>

    <!--简单类型-->
    <bean id="yqBean" class="com.bjpowernode.spring6.bean.QY">
        <!-- 注入简单类型-->
        <property name="loves">
            <array>
                <value>抽烟</value>
                <value>喝酒</value>
                <value>烫头</value>
            </array>
        </property>
        <!--注入非简单类型-->
        <property name="women" >
            <array>
               <ref bean="w1"/>
               <ref bean="w2"/>
            </array>
        </property>
    </bean>

</beans>

write tests

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.bean.Clazz;
import com.bjpowernode.spring6.bean.QY;
import com.bjpowernode.spring6.bean.Student;
import com.bjpowernode.spring6.bean.User;
import com.bjpowernode.spring6.jdbc.MyDateSource;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SetDITest {
    @Test
    public void testArraySet(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-array.xml");
        QY yqBean = applicationContext.getBean("yqBean", QY.class);
        System.out.println(yqBean);
    }

}

Results of the:

Main points:

If the array is a simple type, use the value tag.

If there are non-simple types in the array, use the ref tag.

3.6 Inject List collection and Set collection

Person class

package com.bjpowernode.spring6.bean;

import java.util.List;
import java.util.Set;

public class Person {
    // 注入List
    private List<String> names;
    // 注入Set集合
    private Set<String> addrs;

    @Override
    public String toString() {
        return "Person{" +
                "names=" + names +
                ", addrs=" + addrs +
                '}';
    }

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

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

spring-collection.xml configuration

If it is an attribute of a List collection or a Set collection, you need to use the <list> tag and <set> tag first, and then write the value and ref tags in the tags for assignment!

<?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.xsd">
     <bean id="personBean" class="com.bjpowernode.spring6.bean.Person">
         <!--List集合-->
         <property name="names">
             <list>
                 <value>张三</value>
                 <value>李四</value>
                 <value>张三</value>
                 <value>王五</value>
             </list>
         </property>
         <!--Set集合-->
         <property name="addrs">
             <set>
                 <value>张三</value>
                 <value>李四</value>
                 <value>张三</value>
                 <value>王五</value>
             </set>
         </property>
     </bean>
</beans>

write tests

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.bean.*;
import com.bjpowernode.spring6.jdbc.MyDateSource;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SetDITest {
    @Test
    public void testCollectionSet(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-collection.xml");
        Person personBean = applicationContext.getBean("personBean", Person.class);
        System.out.println(personBean);
    }

}

Results of the:

From the execution results, it can be concluded that the List collection is ordered and repeatable, and the Set collection is disordered and non-repeatable!

Note: Use the list tag when injecting the List collection, use the set tag when injecting the Set collection, use the value tag if the collection is a simple type, and use the ref tag otherwise.

3.7 Inject Map and Properties collections

The Properties collection is essentially a Map collection, but the key and value of the Properties collection can only be of String type, and the injection method is also different from the Map collection!

man class

package com.bjpowernode.spring6.bean;

import java.util.Map;
import java.util.Properties;

public class Man {
    // 注入Map集合
    private Map<String,Integer> phones;
    // 注入Properties
    private Properties properties;

    @Override
    public String toString() {
        return "Man{" +
                "phones=" + phones +
                ", properties=" + properties +
                '}';
    }

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

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

spring-collection.xml configuration

If it is an attribute of the Map collection, use the map tag to nest the entry sub-tag (the ref and value tags are not used anymore)

If it is a property of the Map collection, use the props tag to nest the pro tag

<?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.xsd">
    
    <bean id="manBean" class="com.bjpowernode.spring6.bean.Man">
        <!--Map集合-->
        <property name="phones">
            <map>
                <entry key="张三" value="123"/>
                <entry key="李四" value="456"/>
                <entry key="王五" value="789"/>
            </map>
        </property>
       <!-- Properties集合-->
        <property name="properties">
            <props>
                <prop key="driver">com.mysql.jdbc.driver</prop>
                <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
            </props>
        </property>
    </bean>

</beans>

Results of the:

Main points:

Use the <map> tag for the Map collection, and use the <props> tag to nest the <prop> tag for Properties.

If the key is a simple type, use the key attribute, otherwise use the key-ref attribute.

If the value is a simple type, use the value attribute, otherwise use the value-ref attribute.

3.8 Injecting null and empty strings

Cat class

package com.bjpowernode.spring6.bean;

public class Cat {
    private String name;
    private int age;

    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

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

set-di.xml configuration

①Inject an empty string using: <value/> or value="".

② Inject null and use: <null/> or do not assign a value to the 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.xsd">

    <bean id="carBean" class="com.bjpowernode.spring6.bean.Cat">
        <!--注入null-->
        <!--第一种方法:不为该属性赋值-->
        <property name="name" value="张三"/>
        <!--第二种方法:使用null标签,手动注入null-->
        <property name="name">
            <null/>
        </property>
        <property name="age" value="18"/>

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


</beans>

3.9 The injected value contains special symbols

(1) There are 5 special characters in XML, namely: <, >, ', ", &

(2) The above five special symbols will be treated specially in XML, and will be parsed as part of the XML grammar. If these special symbols appear directly in the injected string, an error will be reported.

Math class

package com.bjpowernode.spring6.bean;

public class Math {
    private String result;

    @Override
    public String toString() {
        return "Math{" +
                "result='" + result + '\'' +
                '}';
    }

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

math.xml configuration

There are two solutions:

The first one: special symbols are replaced by escape characters.

The second method: Put the string containing special symbols into: <![CDATA[]]> . Because the data placed in the CDATA area will not be parsed by the XML file parser.

Note: The method of using <![CDATA[]]> can only use the form of value tag, and cannot use the value attribute!

Note: <![CDATA[]]> is the syntax of XML, and the things placed here will not be parsed by the XML parser!

The escape characters corresponding to the five special characters are:

Special characters

escape character

>

&gt;

<

&lt;

'

&apos;

"

&quot;

&

&amp;

<?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.xsd">
        <bean id="mathBean" class="com.bjpowernode.spring6.bean.Math">
            <!--直接写2<3会报错-->
           <!-- <property name="result" value="2<3"/>-->
            <!--第一种解决方案:使用实体符号代替特殊符号-->
            <property name="result" value="2 &lt; 3"/>
            <!--第二种解决方案:<![CDATA[]]>-->
            <property name="result">
                <!--只能使用value标签-->
                <value><![CDATA[2<3]]></value>
            </property>

        </bean>
</beans>

4. p namespace injection

(1) The p namespace is injected by simplifying the set method.

(2) The prerequisites for using p namespace injection include two:

First: Add the configuration information of the p namespace in the XML header information : xmlns:p=" http://www.springframework.org/schema/p"

Second: p namespace injection is still based on set injection , but p namespace injection can make spring configuration easier; so the corresponding attributes need to provide setter methods .

Dog class: Provides a setter method

package com.bjpowernode.spring6.bean;

import java.util.Date;

public class Dog {
    private String name;
    private int age;
    // 虽然简单类型,但是一般都是当做非简单类型对待
    private Date date;

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", date=" + date +
                '}';
    }
    
    public void setName(String name) {
        this.name = name;
    }

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

    public void setDate(Date date) {
        this.date = date;
    }
}

spring-p.xml configuration

① Add the p namespace to the head of the spring configuration file.
② Use: Use directly behind the class attribute in the <bean> tag, for simple type attribute assignment  p: attribute name = "attribute value" ; for non-simple type attribute assignment p: attribute name-ref = "attribute value" .

<?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">

    <!--原来注入的方式-->
   <bean id="dogBean" class="com.bjpowernode.spring6.bean.Dog">
        <property name="name" value="大黄"/>
        <property name="age" value="3"/>
        <property name="date" ref="nowDate"/>
    </bean>
    <!--p命名注入方式-->
    <bean id="dogBean" class="com.bjpowernode.spring6.bean.Dog" p:name="大黄" p:age="3" p:date-ref="nowDate"/>
    <bean id="nowDate" class="java.util.Date"/>
</beans>

test program

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.bean.Dog;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PTest {
    @Test
    public void testPTest(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-p.xml");
        Object dogBean = applicationContext.getBean("dogBean", Dog.class);
        System.out.println(dogBean);
    }
}

Results of the:

If you comment out the setter method, an error will be reported

5. C namespace injection

(1) The c namespace is injected by the simplified constructor.

(2) Two prerequisites for using the c namespace:

First: You need to add information to the header of the xml configuration file:  xmlns:c=" http://www.springframework.org/schema/c"

②Second : A construction method needs to be provided.

MyTime class: Provides a constructor

package com.bjpowernode.spring6.bean;

public class MyTime {
    private int year;
    private int month;
    private int day;

    public MyTime(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    @Override
    public String toString() {
        return "MyTime{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
}

spring-c.xml configuration

①Add the c namespace to the head of the spring configuration file.
Use: c:_0 subscript method or c:name parameter name method.

<?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">

    <!--原来注入的方式-->
    <bean id="myTimeBean" class="com.bjpowernode.spring6.bean.MyTime">
        <constructor-arg index="0" value="2022"/>
        <constructor-arg index="1" value="1"/>
        <constructor-arg index="2" value="14"/>
    </bean>

    <!--c命名注入方式-->
    <bean id="myTimeBean" class="com.bjpowernode.spring6.bean.MyTime" c:_0="2022" c:_1="1" c:_2="14" />

</beans>

test program

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.bean.MyTime;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class CTest {
    @Test
    public void testCDI(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-c.xml");
        MyTime myTimeBean = applicationContext.getBean("myTimeBean", MyTime.class);
        System.out.println(myTimeBean);

    }
}

Results of the:

If you comment out the constructor

Note: Regardless of the p namespace or the c namespace, simple types and non-simple types can be injected during injection.

6. util namespace

(1) Using the util namespace allows configuration reuse .

(2) The prerequisite for using the util namespace is to add configuration information to the header of the spring configuration file. as follows:

(3) Assuming that the system integrates connection pools from different manufacturers, here we use the data source written by ourselves instead; the configuration of the connection database inside is actually the same, so we can use the util namespace for configuration reuse!

Data source MyDataSource1

package com.bjpowernode.spring6.jdbc;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Properties;
import java.util.logging.Logger;

public class MyDateSource1 implements DataSource {
    // 连接数据库的信息,放到成员变量里
    /*private String driver;
    private String url;
    private String username;
    private String password;*/
    
    // 当然也可以放到一个Properties集合当中
    private Properties properties;

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

    @Override
    public String toString() {
        return "MyDateSource1{" +
                "properties=" + properties +
                '}';
    }

    @Override
    public Connection getConnection() throws SQLException {
        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-util.xml configuration: util namespace not used

<?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.xsd">

    <!--数据源1-->
    <bean id="ds1" class="com.bjpowernode.spring6.jdbc.MyDateSource1">
        <property name="properties">
            <props>
                <prop key="dirver">com.mysql.jdbc.Driver</prop>
                <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
    <!--数据源2-->
    <bean id="ds2" class="com.bjpowernode.spring6.jdbc.MyDateSource2">
        <property name="properties">
            <props>
                <prop key="dirver">com.mysql.jdbc.Driver</prop>
                <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
    </bean>
</beans>

spring-util.xml configuration: use the util namespace, and use util to name the public configuration

After using the util namespace, put the repeated configuration in the util:properties tag, and set a unique identifier id; if you want to use it later, just use the ref attribute to directly import the id.

<?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命名-->
    <util:properties id="prop">
        <prop key="dirver">com.mysql.jdbc.Driver</prop>
        <prop key="url">jdbc:mysql://localhost:3306/spring6</prop>
        <prop key="username">root</prop>
        <prop key="password">123456</prop>
    </util:properties>

    <!--数据源1-->
    <bean id="ds1" class="com.bjpowernode.spring6.jdbc.MyDateSource1">
        <property name="properties" ref="prop" />
    </bean>
    <!--数据源2-->
    <bean id="ds2" class="com.bjpowernode.spring6.jdbc.MyDateSource2">
        <property name="properties" ref="prop"/>
    </bean>
</beans>

test code

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.jdbc.MyDateSource1;
import com.bjpowernode.spring6.jdbc.MyDateSource2;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UtilTest {
    @Test
    public void testUtilTest(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-util.xml");
        MyDateSource1 ds1 = applicationContext.getBean("ds1", MyDateSource1.class);
        MyDateSource2 ds2 = applicationContext.getBean("ds2", MyDateSource2.class);
        System.out.println(ds1);
        System.out.println(ds2);
    }
}

Results of the:

In fact, the util namespace is mainly for collections:

7. XML-based autowiring (byName & byType)

Spring can also complete automatic injection , which is also called automatic assembly. It can be autowired by name (byName) or by type (byType) .

UserDao class

package com.bjpowernode.spring6.dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserDao {
   
   private static final Logger logger = LoggerFactory.getLogger(UserDao.class);

    public void insert(){
        logger.info("数据库正在保存用户信息!");
    }
}

UserDaoService class

package com.bjpowernode.spring6.service;

import com.bjpowernode.spring6.dao.UserDao;

public class UserService {
    private UserDao userDao;

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

    public void saveUser(){
        // 调用UserDao保存用户信息
        userDao.insert();
    }
}

7.1 Automatic assembly according to name (byName)

The following configuration plays a key role:

(1) Autowire="byName" needs to be added to the UserService Bean, indicating that it is assembled by name .

(2) If it is a normal assembly, the id of UserDao can be written casually, as long as it corresponds to the value of the above ref!

(3) If it is an automatic assembly, the id of UserDao must be the setUserDao (set method) method corresponding to the UserDao attribute in the UserService class to remove the previous set, and the value after the first letter becomes lowercase: userDao!

(4) So automatic configuration based on name is essentially set injection!

spring-autowire.xml configuration

<?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.xsd">

    <!--正常的装配-->
    <bean id="userServiceBean" class="com.bjpowernode.spring6.service.UserService">
        <property name="userDao" ref="userDaoBean"/>
    </bean>
    <bean id="userDaoBean" class="com.bjpowernode.spring6.dao.UserDao"/>

    <!--根据名称自动装配-->
    <bean id="userServiceBean" class="com.bjpowernode.spring6.service.UserService" autowire="byName"/>
    <bean id="userDao" class="com.bjpowernode.spring6.dao.UserDao"/>
</beans>

write tests

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.service.UserService;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AutowireTest {
    @Test
    public void testAutowireTest(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-autowire.xml");
        UserService userServiceBean = applicationContext.getBean("userServiceBean", UserService.class);
        userServiceBean.saveUser();
    }
}

Results of the:

Normal execution means that if it is assembled according to the name (byName), the bottom layer will call the set method for injection! For example: setAge() corresponds to age, setPassword() corresponds to password, and setEmail() corresponds to email.

7.2 Automatic assembly according to type (byType)

(1) In fact , whether it is automatically equipped byName according to the name or braked byType according to the type, it is based on the set method when assembling , so the set method must be provided!

(2) When auto-assembling according to byType, for the injected object, you only need to use the bean tag to specify the type to be injected, and you don't need to specify the id.

spring-autowire.xml configuration

<?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.xsd">

    <!--根据类型自动装备-->
    <bean id="userServiceBean" class="com.bjpowernode.spring6.service.UserService" autowire="byType"/>
    <bean class="com.bjpowernode.spring6.dao.UserDao"/>
</beans>

Results of the:

If byType is assembled according to type, what will happen if there are two beans of the same type in the configuration file?

<?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.xsd">
    <!--两个类型一样的bean-->
    <bean id="x" class="com.bjpowernode.spring6.dao.UserDao"/>
    <bean id="y" class="com.bjpowernode.spring6.dao.UserDao"/>
    <bean id="userServiceBean" class="com.bjpowernode.spring6.service.UserService" autowire="byType"/>
</beans>

Results of the: 

The test results show that when byType performs automatic assembly, a certain type of Bean in the configuration file must be unique, and there cannot be more than one!

8. Spring introduces external attribute configuration files (using the context namespace)

We all know that when writing a data source, information about connecting to the database is needed, such as: driver, url, username password and other information. Can this information be written separately into a properties configuration file? In this way, it will be more convenient for users to modify it. Of course, it is possible to use the context namespace!

Step 1: Write a data source class and provide relevant properties

package com.bjpowernode.spring6.jdbc;

import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

public class MyDateSource implements DataSource {
    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 "MyDateSource{" +
                "driver='" + driver + '\'' +
                ", url='" + url + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public Connection getConnection() throws SQLException {
        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;
    }
}

Step 2: Create a new jdbc.properties file under the classpath and configure the information

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/spring6
username=root
password=123456

 Step 3: Introduce the context namespace in the spring-properties.xml configuration file

<?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">

</beans>

Step 4: Configure and use the jdbc.properties file in spring

The first step: introduce the context namespace, which has been cited before.

Step 2: Use the location attribute of the <context:property-placeholder> tag to specify the path of the property configuration file. location loads resources from the root path of the class by default .

<?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:property-placeholder location="jdbc.properties"/>

    <bean id="dataSource" class="com.bjpowernode.spring6.jdbc.MyDateSource">
        <!--使用$元符号,${key}-->
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
    </bean>
</beans>

test program:

package com.bjpowernode.spring6.test;

import com.bjpowernode.spring6.jdbc.MyDateSource;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class JDBCPropertiesTest {
    @Test
    public void testProperties(){
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-properties.xml");
        MyDateSource dataSource = applicationContext.getBean("dataSource", MyDateSource.class);
        System.out.println(dataSource);
    }
}

 Results of the:

Why is username not in our configuration file here? Spring is loaded through ${}, and the default is to load the environment variables of the windows system first!

 How to deal with it? Generally add the jdbc prefix in front of all configurations

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring6
jdbc.username=root
jdbc.password=123456

Results of the: 

Guess you like

Origin blog.csdn.net/m0_61933976/article/details/128658072