Spring学习笔记-03 Spring测试、JdbcTemplate体验、Bean生命周期、Bean后置处理器

1. Spring测试:

我们测试Spring需要手动读取配置文件,getBean,但是Spring也为我们提供了自动化的测试方法。

1)引入springd-test依赖,注意这个测试的包需要与我们引入的spring框架的包版本一致,并且不同的版本所支持的最低junit版本也不一致,本人使用的是5.2.6,最低需要junit 4.12的支持。

    <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)使用注解替代和自动装配替代手动读取配置文件和装配bean

2. jdbcTemplate:Spring提供的一款操作数据库的模板(感受IoC)。

1)引入依赖(使用Druid连接池)

        <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)现在我们使用Spring管理,所以需要用的类得先注入Spring容器才行,并为jdbcTemplate配置使用的连接池

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

这边注意一下,在xml文件中,使用字符&需要转义成&amp;。

3)测试

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

    @Autowired
    private JdbcTemplate jdbcTemplate;

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

}

当然了,后续的开发我们还是以使用Mybatis为主流,这边的演示时为了展示Spring集成开发环境。

我们再试试用java配置类配置:

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

}

实际上@Bean注解配合方法生产对象就替代了<bean>标签,属性注入根据Name或者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的生命周期

1)编写实体类,在方法上增加打印输出

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)在配置文件中注册对象

    <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)方法测试

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

可见,在读取并解析配置文件的时候,Spring已经创建对象了,而容器管理的对象随着容器的销毁而销毁。注入调用setter的顺序与配置文件中定义的属性先后顺序有关。Bean的生命周期为 构造 - 注入 - 初始化 - 使用 - 销毁。

[注]:如果我们使用的是构造器注入,那么实际上就不会调用setter方法。

    <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后置处理器

Spring提供了后置处理器,帮助我们在Bean初始化前和初始化后对Bean进行一些操作。

1)继承后置处理器类,覆写初始化前和初始化后两个方法。

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)在Spring容器中注册,由于我们本身不需要使用这个对象,因此直接给出class即可,无需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)测试调用

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

[注]:这有点类似于拦截器,一旦注入Spring容器后,它会自动拦截所有的bean,并调用我们覆写的方法。

完整的Bean生命周期为 构造 - 注入 - 初始化前 - 初始化 - 初始化后 - 使用 - 销毁。

猜你喜欢

转载自blog.csdn.net/qq_39304630/article/details/112388144
今日推荐