I won't use Spring's configuration file, so I'll leave it to him

Absrtact: from the rapid use of Spring program, the use of Bean tag and the specific use of its attributes, each attribute is explained by code, and the running results and cases are also written very clearly.

This article is shared from Huawei cloud community< How do I use Spring configuration files? Let's play with the Spring configuration file >Author: I am a cabbage.

1, Spring application quick start

Step 1: import the coordinates of the basic package developed by Spring

Create a maven project and import the dependencies required by Spring. In order to facilitate testing, I also imported a Junit test package

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.14</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

Step 2: write Dao interface and implementation class

Next, you need to write a Dao interface and its implementation class to build a testing environment. If you don't say much, you can write the code directly

public interface UserDao {
    void save();
}
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
        System.out.println("Saved successfully~~");
    }
}

Step 3: create Spring core configuration file

After the interface and class are written, I start to get to the point. I create the core configuration file of Spring under the class path (resources). I call it ApplicationContext xml

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

Step 4: configure the UserDaoImpl class in the Spring configuration file

After creating the xml configuration file, if I want to call the save() method, I need to create an object of UserDaoImpl class. Here, I use the container method.

    <bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean>

The id here is user-defined, preferably the first letter of the class name in lowercase, which is convenient for memory. The class attribute value is the package path where the class object is to be created. The package path where my UserDaoImpl class is located is com sht. dao. impl. UserDaoImpl, you can't write it wrong!

Step 5: use the Spring API to obtain the Bean instance

Next, test:

public class UserDaoDemo {
    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userdao = (UserDao) applicationContext.getBean("userdao");
        userdao.save();
    }
}

Get the container - applicationContext through new ClassPathXmlApplicationContext("applicationContext.xml"), and then get the object of UserDaoImpl class through the attribute value corresponding to id, so we don't need to create the object in a new way!

The above java code can also be written in another way:

public class UserDaoDemo {
    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDaoImpl userDao = applicationContext.getBean(UserDaoImpl.class);
        userDao.save();
    }
}

Where, when the data type of the parameter is a string, it means that the Bean instance is obtained from the container according to the Bean id, and the return is Object, which needs to be forced.

When the data type of the parameter is Class, it means that Bean instances are matched from the container according to the type. Special attention: when there are multiple beans of the same type in the container, this method will report an error.

Operation results:

The result is correct. Now that you have a basic understanding of the spring configuration file, let's take a look at other details in the spring configuration file!

2, Spring configuration file usage

1. Bean tag basic configuration

Basic introduction

The configuration object is created by Spring

By default, it calls the parameterless constructor in the class. If there is no parameterless constructor, it cannot be created successfully. For the parameterless constructor, we will talk about it later

Basic properties

id: the unique identifier of the Bean instance in the Spring container
class: the fully qualified name of the Bean

These two basic properties have been used in the quick start, so I won't introduce them at most

Bean tag scope configuration

Modify the xml configuration file and add scope="singleton" to the original bean, which means that no matter how many objects we create, they are the same

<bean id="userdao" class="com.sht.dao.impl.UserDaoImpl" scope="singleton"></bean>

Write a test code

    public void test1(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userdao1 = (UserDao) context.getBean("userdao");
        System.out.println(userdao1);
        UserDao userdao2 = (UserDao) context.getBean("userdao");
        System.out.println(userdao2);
        System.out.println("Whether it is the same object instance:" + (userdao1 == userdao2));
    }

Operation results:

Continue to modify the xml configuration file and change the scope="singleton" to scope="prototype", which means that when we use it to create objects, it is not the same object instance

The above test code remains unchanged, and the running results are as follows:

Bean tag instantiation timing

Friends may have questions. When did the above two methods create object instances? Don't worry, let's take our time.

In order to facilitate the display of the effect, I added a sentence of code to the nonparametric constructor of UserDaoImpl class to distinguish the time of creating an instance

  public UserDaoImpl(){
        System.out.println("UserDaoImpl Start creating");
    }

When scope is singleton

Run debug and click F8

We can find that the object instance is created from the time the configuration file is loaded

When scope is prototype

Run debug and press F8. It is found that the console does not print "UserDaoImpl start creation", indicating that the configuration file does not load the object instance

Press F8 again to next

We can find that the console finally prints "UserDaoImpl start creation"

summary

When the scope value is singleton, when the application loads and creates a container, the object is created; When the scope value is prototype, a new object instance is created only when an object is used.

Bean lifecycle configuration

Add two methods to the UserDaoImpl class

  public void init(){
        System.out.println("Initialization method");
    }
  public void destory(){
        System.out.println("Destruction method");
    }

Modify the xml configuration file, init method: specify the initialization method name in the class, destroy method: specify the destruction method name in the class

<bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"
          scope="singleton"
          init-method="init"
          destroy-method="destory">
</bean>

Write test code

public void test3(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userdao1 = (UserDao) context.getBean("userdao");
        System.out.println(userdao1);
        UserDao userdao2 = (UserDao) context.getBean("userdao");
        System.out.println(userdao2);
        System.out.println("Whether it is the same object instance:" + (userdao1 == userdao2));
        //This is used to close the container
        ((ClassPathXmlApplicationContext) context).close();
    }

Operation results:

From this example, I believe you can infer the order of object creation, initialization, method call and destruction

There are three ways to instantiate a Bean

Method 1: instantiation of parameterless construction method (key)

In fact, we have been using this method before, but it should be noted that this method will create class objects according to the default parameterless constructor. If there is no default parameterless constructor in the bean, the creation will fail

Method 2: Factory static method instantiation (understand)

Create a static factory class and directly return the object instance of UserDaoImpl class

public class StaticFactory {
    public static UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

For bean s that write xml configuration files, the class attribute value here is the path of the package corresponding to the static factory class, and the attribute value corresponding to factory method is the method name in the class

<bean id="userdao" class="com.sht.factory.StaticFactory" factory-method="getUserDao"></bean>

Write code test

public class UserDaoDemo {
    public static void main(String[] args) {
        ApplicationContext applicationContext =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userdao = (UserDao) applicationContext.getBean("userdao");
        userdao.save();
    }
}

The final running result will be: "save successfully ~ ~"

Method 3: factory instance method instantiation (understand)

Create a factory class and return the object instance of UserDaoImpl class

public class DynamicFactory {
    public UserDao getUserDao(){
        return new UserDaoImpl();
    }
}

For the bean that writes the xml configuration file, the class attribute value here is the path of the package corresponding to the factory class. The first bean can get the object of the factory class, and then write a bean to get the object instance of UserDaoImpl class. The factory bean attribute value represents the factory from which it is taken. The attribute value corresponding to factory method is the method name in the class

<bean id="factory" class="com.sht.factory.DynamicFactory"></bean>
<bean id="userdao" factory-bean="factory" factory-method="getUserDao"></bean>

The final running result is: "save successfully ~ ~"

summary

2. Dependency injection of Bean

Basic introduction

Dependency Injection: it is the concrete implementation of the Spring framework core IOC.

When writing the program, the creation of objects is handed over to Spring through control inversion, but there can be no dependency in the code. IOC decoupling only reduces their dependencies, but it will not eliminate them. For example, the business layer will still call the methods of the persistence layer.

After using Spring, Spring can maintain the dependency between the business layer and the persistence layer.
Simply put, it means waiting for the framework to transfer the persistence layer object to the business layer without getting it ourselves.

Dependency injection method of Bean

Method 1: parametric construction method

We talked about the nonparametric construction method. Now we talk about the parametric construction method. Let's first create a UserService interface and its implementation class UserServiceImpl

public interface UserService {
    void save();
}
public class UserServiceImpl implements UserService {
    private UserDao userdao;
    public UserServiceImpl(UserDao userdao) {
        this.userdao = userdao;
    }
    @Override
    public void save() {
        userdao.save();
    }
}

For the bean that writes the xml configuration file, the class attribute value corresponds to the package path under the class respectively< The name attribute value in constructor Arg name = "userdao" ref = "userdao" > < / constructor Arg > is the lowercase initial of the corresponding set method name after removing set. Ref is the imported data type, that is, it represents the injection of object attributes

  <bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean>
  <bean id="userService"  class="com.sht.service.impl.UserServiceImpl">
        <constructor-arg name="userdao" ref="userdao"></constructor-arg>
  </bean>

Mode 2: set method

The interface remains unchanged. Change the UserServiceImpl class. It should be noted that the permission of setUserdao() is public and cannot be written as private

public class UserServiceImpl implements UserService {
    private UserDao userdao;
    //Permission is public
    public void setUserdao(UserDao userdao){
        this.userdao = userdao;
    }
    @Override
    public void save() {
        userdao.save();
    }
}

I won't explain the class attribute of the bean that writes the xml configuration file. It focuses on < property name = "userdao" ref = "userdao" > < / property >; The name attribute value is the lowercase initial of the corresponding set method name after removing set. Ref is the imported data type, that is, it indicates the injection of object attributes; Here, inject the object of UserDaoImpl class into UserServiceImpl class, and you can call its save() method

  <bean id="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean>
  <bean id="userService"  class="com.sht.service.impl.UserServiceImpl">
        <property name="userdao" ref="userdao"></property>
  </bean>
Test code:
public void test5(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.save();
    }

Operation results:

In addition, there is a special method in the set method: P namespace injection. Its essence is also set method injection, but it is more convenient than the above set method injection, which is mainly reflected in the configuration file, as follows:

Introducing xmlns:p=“ http://www.springframework.org/schema/p "Namespace. Secondly, the P: userdao ref attribute value has the same meaning as the attribute value corresponding to Ref. this method can be used to understand

<?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="userdao" class="com.sht.dao.impl.UserDaoImpl"></bean>  
    <bean id="userService" class="com.sht.service.impl.UserServiceImpl" p:userdao-ref="userdao"></bean>
</beans>

3. Dependency injection data type of Bean

Injection of common data types

I use the set method to explain the dependency injection of bean s. Continue to add two basic data types and their set methods to the UserDaoImpl class

    private String name;
    private Integer age;
    public void setName(String name) {
        this.name = name;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public void show() {
        System.out.println("The name is" + name + "What is your age" + age);
    }

Modify the bean of the xml configuration file. The attribute value of name represents the name of the set method, and the attribute value of value represents the attribute value you want to fill in

<bean id="userDao" class="com.sht.dao.impl.UserDaoImpl">
        <property name="name" value="Cabbage"></property>
        <property name="age" value="20"></property>
</bean>

Write a test class:

   public void test7(){
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDaoImpl contextBean = context.getBean(UserDaoImpl.class);
        contextBean.show();
    }

Operation results:

Injection of collection data types

List < string > type injection

Continue in UserDaoImpl Code changed in class:
    private List<String> stringList;
    public void setStringList(List<String> stringList) {
        this.stringList = stringList;
    }
    public void showStringList() {
        System.out.println(stringList);
    }

Modify the xml configuration file and inject two basic data types, namely < list > and < value >

  <bean id="userDao" class="com.sht.dao.impl.UserDaoImpl">
       <property name="stringList">
          <list>
              <value>111</value>
              <value>222</value>
              <value>333</value>
          </list>
       </property>
  </bean>

Operation results:

List < user > type injection

First, create a User class with corresponding get and set methods and toString methods to facilitate testing

public class User {
    private Integer id;
    private String username;
    private String password;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

Modify the bean of the xml configuration file. It can be seen that, unlike before, the < ref > tag is used in < list >, which represents the injected reference data type

 <bean id="user01" class="com.sht.domain.User">
        <property name="id" value="1"></property>
        <property name="username" value="Cabbage"></property>
        <property name="password" value="123456"></property>
 </bean>
 
    <bean id="user02" class="com.sht.domain.User"></bean>
 
    <bean id="userDao" class="com.sht.dao.impl.UserDaoImpl">
       <property name="userList">
           <list>
               <ref bean="user01"></ref>
               <ref bean="user02"></ref>
           </list>
       </property>
    </bean>

Operation results:

Map < string, user > type injection

Continue to change the code in the UserDaoImpl class:

    private Map<String, User> stringUserMap;
    public void setStringUserMap(Map<String, User> stringUserMap) {
        this.stringUserMap = stringUserMap;
    }
    public void showStringUserMap() {
        System.out.println(stringUserMap);
    }

Modify the xml configuration file. The difference is that when using map, the tags use < Map > and < entry >, which are similar to the list tag

    <bean id="user01" class="com.sht.domain.User">
        <property name="id" value="1"></property>
        <property name="username" value="Cabbage"></property>
        <property name="password" value="123456"></property>
    </bean>

    <bean id="userDao" class="com.sht.dao.impl.UserDaoImpl">
        <property name="stringUserMap">
         <map>
             <entry key="key1" value-ref="user01"></entry>
         </map>
        </property>
    </bean>

Operation results:

It should be noted that when selecting the key attribute, we will be prompted with a key ref as shown in the figure, which means that the key we want to use is an imported data type. Because the key I use is String, I choose key

When using value ref, the value will also appear, and its usage is the same as above

Property type injection

Continue to change the code in the UserDaoImpl class:

    private Properties properties;
    public void setProperties(Properties properties) {
        this.properties = properties;
    }
    public void showProperties(){
        System.out.println(properties);
    }

The difference between modifying the xml configuration file and the previous one is that the tags use < props > and < prop >, and the method is similar to the above method

 <bean id="userDao" class="com.sht.dao.impl.UserDaoImpl">
       <property name="properties">
           <props>
               <prop key="key01">value1</prop>
               <prop key="key02">value2</prop>
           </props>
       </property>
 </bean>

Operation results:

4. Introduce other configuration files (sub module development)

Create a new configuration file applicationcontext1 XML. In the actual development, there are many Spring configurations, which leads to the complexity and large volume of Spring configuration. Therefore, some configurations can be disassembled into other configuration files, and loaded in the main Spring configuration file through the import tag

Put applicationcontext1 The configuration content in the XML configuration file is introduced into ApplicationContext Implementation of XML:

<import resource="applicationContext1.xml"></import>

summary

The above are the relevant knowledge points of Spring configuration files. Let's take a look at the key configurations of Spring:

 

Click focus to learn about Huawei cloud's new technologies for the first time~

Keywords: Java Junit Maven Spring entry

Added by cneale on Fri, 21 Jan 2022 15:57:03 +0200