Spring study notes -03 Spring test, JdbcTemplate experience, Bean life cycle, Bean post processor

1. Spring test:

We need to manually read the configuration file, getBean, to test Spring, but Spring also provides us with automated testing methods.

1) Introduce springd-test dependency. Note that the package for this test needs to be consistent with the package version of the spring framework we introduced, and the minimum junit version supported by different versions is also inconsistent. I use 5.2.6, and the minimum junit 4.12 support.

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--引入web会将所有的spring相关依赖全部导入-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <!--引入Spring测试环境-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
    </dependencies>

2) Use annotation substitution and automatic assembly instead of manually reading configuration files and assembly beans

2. jdbcTemplate: A template for operating database provided by Spring (feeling IoC).

1) Introduce dependency (using Druid connection pool)

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>

2) Now we use Spring management, so the classes that need to be used must be injected into the Spring container first, and the connection pool used for jdbcTemplate is configured

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="username" value="root"/>
        <property name="password" value="zjm@?42393"/>
        <property name="url" value="jdbc:mysql://localhost:3306/study_mybatis?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false"/>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    </bean>

Note here that in the xml file, the character & needs to be escaped into &.

3) Test

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:beans.xml")
public class TestFirst {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Test
    public void testCreateBean(){
        jdbcTemplate.execute("select * from t_user");
    }

}

Of course, we will continue to use Mybatis as the mainstream for subsequent development. The demonstration here is to show the Spring integrated development environment.

Let's try again with the java configuration class configuration:

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import javax.sql.DataSource;

@Configuration
public class jdbcConfig {

    @Bean
    public DataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("zjm@?42393");
        dataSource.setUrl("jdbc:mysql://localhost:3306/study_mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource){
        return new JdbcTemplate(dataSource);
    }

}

In fact, the @Bean annotation and method production object replaces the <bean> tag, and attribute injection is based on Name or Type.

import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;

public class TestJdbcConfig {
    @Test
    public void testConfigJava(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(jdbcConfig.class);
        JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class);
        List<Map<String, Object>> maps = jdbcTemplate.queryForList("select * from t_user");
        for (Map<String, Object> map : maps) {
            System.out.println(map);
        }
    }
}

3. Bean life cycle

1) Write entity classes and add printouts to methods

package com.zt.entity;

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

    public Student() {
        System.out.println("-----构造-----");
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        System.out.println("-----注入name-----");
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        System.out.println("-----注入age-----");
        this.age = age;
    }

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

    public void init(){
        System.out.println("-----初始化-----");
    }

    public void destory(){
        System.out.println("-----销毁-----");
    }
}

2) Register the object in the configuration file

    <bean id="student" class="com.zt.entity.Student" init-method="init" destroy-method="destory">
        <property name="age" value="22"/>
        <property name="name" value="zzt"/>
    </bean>

3) Method testing

    @Test
    public void testBean(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        System.out.println("-----获取对象前-----");
        Student student = context.getBean("student", Student.class);
        System.out.println(student);
        context.close();
    }

It can be seen that when the configuration file is read and parsed, Spring has already created the object, and the container-managed object is destroyed as the container is destroyed. The order in which the setters are injected is related to the order of the attributes defined in the configuration file. The life cycle of Bean is construction-injection-initialization-use-destruction.

[Note]: If we are using constructor injection, then the setter method will not actually be called.

    <bean id="student" class="com.zt.entity.Student" init-method="init" destroy-method="destory">
        <constructor-arg name="age" value="22"/>
        <constructor-arg name="name" value="zzt"/>
    </bean>

4. Bean post processor

Spring provides a post processor to help us perform some operations on Bean before and after initialization.

1) Inherit the post processor class and override the two methods before and after initialization.

package com.zt.handlers;

import com.zt.entity.Student;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class BeanHandler implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("-----初始化前处理-----");
        if( bean instanceof Student ){
            Student student = (Student) bean;
            if("zzt".equals( student.getName() )){
                System.out.println("wife");
            }else if("zjm".equals( student.getName() )){
                System.out.println("husband");
            }
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("-----初始化后处理-----");
        return bean;
    }
}

2) Register in the Spring container. Since we don't need to use this object, we can directly give the class without the bean id.

    <bean id="student" class="com.zt.entity.Student" init-method="init" destroy-method="destory">
        <property name="age" value="22"/>
        <property name="name" value="zzt"/>
    </bean>

    <bean class="com.zt.handlers.BeanHandler"/>

3) Test call

public class BeanLife {
    @Test
    public void testBean(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        System.out.println("-----获取对象前-----");
        Student student = context.getBean("student", Student.class);
        System.out.println(student);
        context.close();
    }
}

[Note]: This is similar to an interceptor. Once injected into the Spring container, it will automatically intercept all beans and call the method we override.

The complete Bean life cycle is construction-injection-before initialization-initialization-after initialization-use-destruction.

Guess you like

Origin blog.csdn.net/qq_39304630/article/details/112388144