Spring系列教程六: Spring基于注解的Ioc以及Ioc案例

学习基于注解的Ioc配置,咱们脑海中须要有一个认知,就是注解配置和xml配置实现的功能都是同样的,都是要下降程序间的耦合,只是配置的形式不同java

在实际开发中究竟是使用xml仍是注解,每一个公司有不一样的使用习惯,全部这两种配置方式咱们都须要掌握mysql

咱们在讲解注解配置时,采用上一章的案例,把Spring的xml配置内容改成使用注解逐步实现spring

一、Spirng中Ioc的经常使用注解按照做用分类

用于建立对象:做用是和xml配置文件中编写一个bean标签建立对象的功能是同样的

@Component(如下三个是Spring框架为咱们明确提供的三层使用注解,使咱们的三层对象更加清晰,如下是Component的衍生类)sql

Controller(这个对象通常用在表现层)数据库

Service(这个对象一遍用于业务层)apache

Repository(这个业务通常用于持久层)
做用:把当前对象存入Spring容器中
属性:value 用于指定bean的id,当咱们不写的时候,它的默认是当前类名,且首字母小写,也能够指定一个名称app

①在接口中实现@Component的代码改写

@Component("accountServiceImpl4")
public class AccountServiceImpl4 implements IAccountService {

   private String name;
   private Integer age;
   private Date brithday;

   AccountServiceImpl4(String name, Integer age, Date brithday){
       this.name=name;
       this.age=age;
       this.brithday=brithday;
   }

   public void saveAccount(){
       System.out.println("service中的saveAccount方法执行了...."+name+age+brithday);
   }
}

②配置文件中改写(须要新添加引入context的约束)

<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
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/tx">
    <!--新添加一个约束:告诉Spring在建立容器时要扫描的包,配置所须要的标签不是在bean的约束中,而是一个名称为
    context的名称和空间中,这个时候就会扫描base-pack类上或者接口上的注解-->
    <context:component-scan base-package="com.ithema.jdbc"></context:component-scan>
</beans>

③测试类框架

package com.ithema.jdbc.ui;
import com.ithema.jdbc.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * 模拟一个表现层,用于调用业务层
 */
public class Client2 {
    public static void main(String[] args) {
        ApplicationContext ac=new ClassPathXmlApplicationContext("ApplicationContext2.xml");
        IAccountService as= (IAccountService) ac.getBean("accountServiceImpl4");
        System.out.println(as);
        as.saveAccount();
    }
}

显示结果以下ide

用于注入数据:做用是和xml配置文件中编写一个property标签建立对象的功能是同样的

Autowired单元测试

做用:自动按照类型注入,主要容器中有惟一一个bean对象和要注入的变量类型匹配,就能够注入成功,若是Ioc容器中没有任何bean类型和要注入的变量类型匹配,则报错

若是有Ioc容器中有多个匹配类型:首先按照类型圈定出来匹配的对象,使用变量名称做为bean的id,在圈定出来的两个里面继续查找,若是bean id有同样也能够注入成功

出现位置:能够是变量上,也能够是方法上

细节:在使用注解注入时候,set方法就不用了

可是这种状况不是咱们想看到的,那么有新的方法吗??以下

Qualifier(不能独立使用,须要和Autowired配合使用,有解决的方案吗?以下一个属性)

做用:在按照类中注入的基础上再按照名称注入,它在给类成员注入时,不能单独使用,但在给方法参数注入时候能够

属性:value 用于指定bean的id

Resource:直接按照bean的id注入,平时用的比较多,它能够独立使用

@Resource(name="accountDao")

以上三个注解只能注入其余bean类型的数据,而基本数据类型和String类型没法使用上述注解实现另外,集合类型的注入只能使用xml来实现,怎么解决以下

Value:

做用:涌入注入基本类型和String类型的数据

属性 value:用于指定数据的值,它可使用Spring中spel(也就是Spring中的el表达式),spel写法$(表达式)

①接口上修改代码

②启动测试类显示结果以下,成功注入数据

存在一bean对象时候

存在多个bean对象时候,要注入的变量名称和某个bean的id保持一致也能够注入成功

 

用于改变做用范围:他们的做用是和xml配置文件中编写一个scope标签的功能是同样的

做用:用于指定bean的做用范围,属性:value 指定范围取值,经常使用取值singleton(默认值)/prototype

测试以下,做用范围默认是单例的

那么若是咱们把做用范围改为prototype的啦?结果固然是false

和生命周期相关:他们的做用是和xml配置文件中编写一个init-method和destory-method标签的功能是同样的

PreDestory 做用:用于指定销毁方法

PostConstruct 做用:初始化方法

 

二、使用xml方式和注解方式实现单表的CURD操做,持久技术层选用dbutils(案例)

项目目录

StudentDao方法接口

package com.it.dao;

import com.it.entity.Student;

import java.util.List;

public interface StudentDao {

    List<Student> findAllStudent();

    Student findByid(int id);

    void saveStudent(Student student);

    void updateStudent(Student  student);

    void deleteStudent(int id);
}

StdentDao接口实现类

package com.it.dao;

import com.it.entity.Student;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;
@Repository("StudentDao")
public class StudentDaoImpl implements StudentDao {

    @Autowired
    private  QueryRunner runner;

    @Override
    public List<Student> findAllStudent() {
        //BeanListHandler将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里
        try{
            return runner.query("select * from student",new BeanListHandler<Student>(Student.class));
        }catch (Exception e){
            throw  new RuntimeException(e);
        }

    }

    @Override
    public Student findByid(int id) {
        //BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中
        try{
            return runner.query("select * from student where id=?",new BeanHandler<Student>(Student.class),id);
        }catch (Exception e){
            throw  new RuntimeException(e);
        }
    }

    @Override
    public void saveStudent(Student student) {
        try{
            runner.update("insert into student(id,stuno,name,classid)values(?,?,?,?)",student.getId(),student.getStuno(),student.getName(),student.getClassid());
        }catch (Exception e){
            throw  new RuntimeException(e);
        }

    }

    @Override
    public void updateStudent(Student student) {
        try{
            runner.update("update student set stuno=?,name=?,classid=? where id=?",student.getStuno(),student.getName(),student.getClassid(),student.getId());
        }catch (Exception e){
            throw  new RuntimeException(e);
        }

    }

    @Override
    public void deleteStudent(int id) {
        try{
            runner.update("delete from student where id=?",id);
        }catch (Exception e){
            throw  new RuntimeException(e);
        }

    }
}

Service层方法接口

package com.it.service;

import com.it.entity.Student;

import java.util.List;


public interface StudentService {
    /**
     * 查找全部学生
     * @return
     */
    List<Student> findAllStudent();

    /**
     * 根据id查找学生
     */
    Student findByid(int id);
    /**
     * 保存操做
     */
    void saveStudent(Student student);
    /**
     * 更新操做
     */
    void updateStudent(Student  student);
    /**
     * 删除操做
     */
    void deleteStudent(int id);
}

Service层接口实现类,这里就是用了注入的方式给StudentDao注入参数

package com.it.service;

import com.it.dao.StudentDao;
import com.it.entity.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository("studentService")
public class StudentServiceImpl implements  StudentService{

    @Autowired
    private StudentDao studentDao;

    @Override
    public List<Student> findAllStudent() {

        return studentDao.findAllStudent();
    }

    @Override
    public Student findByid(int id) {

        return studentDao.findByid(id);
    }

    @Override
    public void saveStudent(Student student)
    {
       studentDao.saveStudent(student);
    }

    @Override
    public void updateStudent(Student student) {

        studentDao.updateStudent(student);
    }

    @Override
    public void deleteStudent(int id) {

        studentDao.deleteStudent(id);
    }
}

学生的实体类

package com.it.entity;

import java.io.Serializable;

/**
 * 学生实体类
 */
public class Student implements Serializable {

    private int id;
    private String stuno;
    private String name;
    private int classid;

    public int getId() {

        return id;
    }

    public void setId(int id) { this.id = id; }

    public String getStuno() {
        return stuno;
    }

    public void setStuno(String stuno) {
        this.stuno = stuno;
    }

    public String getName() {
        return name;
    }

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

    public int getClassid() {
        return classid;
    }

    public void setClassid(int classid) {
        this.classid = classid;
    }

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

父配置类,指定当前类为注解类的标签,Configuration

package com.it.config;

import org.springframework.context.annotation.*;

@Configuration
@Import(JbdcConfig.class)
@ComponentScan("com.it")
@PropertySource("classpath:JdbcConfig.properties")
public class SpringConfiguration {

}

子配置类,主要是配置的链接jdbc的数据库

package com.it.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

import javax.sql.DataSource;

public class JbdcConfig {
    /**
     * 建立dataSource对象
     * @param dataSource
     * @return
     */
    @Value("${jdbc.driver}")
    private  String driver;
    @Value("${jdbc.url}")
    private  String url;
    @Value("${jdbc.username}")
    private  String username;
    @Value("${jdbc.password}")
    private  String password;

    @Bean("runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }

    /**
     * 建立数据源对象
     */
    @Bean("dataSource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
            return  ds;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

下面是配置文件

<?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">
    <!--告诉Spring容器在建立的时候要扫描包,配置所须要的标签不在bean约束中,而是
    在一个叫作context的空降名称和约束中-->
    <context:component-scan base-package="com.it"></context:component-scan>
    <!--配置QuerryRunner对象-->
    <bean id="runner" class="org.apache.commons.dbutils.QueryRunner" scope="prototype">
        <!--注入数据源-->
        <constructor-arg name="ds" ref="dataSource"></constructor-arg>
    </bean>
    <!--配置数据-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/fresh?characterEncoding=UTF-8"></property>
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
    </bean>
</beans>

数据库配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/fresh?characterEncoding=UTF-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=root

日志输出文件配置,主要是配置输出到控制台

log4j.rootLogger=info,CONSOLE

#############################################################
# Console Appender
#############################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=info
##log4j.appender.CONSOLE.DatePattern=yyyy-MM-dd
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%4p]:%m%n'
##输出到文件

##添加到数据库

最后是测试类,这里咱们采用了spring整合junit4的方式

package com.it;

import com.it.config.SpringConfiguration;
import com.it.entity.Student;
import com.it.service.StudentService;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;


/**
 * **
 *  * 使用Junit单元测试:测试咱们的配置
 *  * Spring整合junit的配置
 *  *      一、导入spring整合junit的jar:spring-test(坐标)
 *  *      二、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
 *  *             @Runwith
 *  *      三、告知spring的运行器,spring和ioc建立是基于xml仍是注解的,而且说明位置
 *  *          @ContextConfiguration
 *  *                  locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
 *  *                  classes:指定注解类所在地位置
 *  *
 *  *   当咱们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上
 *  */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class TestClient {
    Logger logger=Logger.getLogger(TestClient.class);
    @Autowired
    private  StudentService as;
    @Test
    public  void findAll(){
        List<Student> studentList =as.findAllStudent();
        for (Student student:studentList) {
            //System.out.println(student);
            logger.info(student);
        }
    }

    @Test
    public  void findbyidtest() {
        //ApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Student student = as.findByid(4);
        logger.info(student);
    }

    @Test
    public  void saveTest() {
        Student student=new Student();
        student.setId(7);
        student.setStuno("10007");
        student.setName("陈多糖");
        student.setClassid(2);
        as.saveStudent(student);
    }
    @Test
    public  void updatetest() {
        Student student = as.findByid(4);
        student.setName("陈柳柳");
        as.updateStudent(student);
    }

    @Test
    public  void deletetest() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        StudentService as = ac.getBean("studentService", StudentService.class);
        as.deleteStudent(7);
    }
}

输出结果以下

 

三、改造基于注解的Ioc案例,使用注解的方式实现Spring的一些新注解的使用

如何实如今不是咱们本身写类上的注解,好比咱们引入QueryRunner类

基于注解的 IoC 配置已经完成,可是你们都发现了一个问题:咱们依然离不开 spring 的 xml 配置文件,那么能不能不写这个 bean.xml,全部配置都用注解来实现呢?固然,咱们们也须要注意一下,咱们选择哪一种配置的原则是简化开发和配置方便,而非追求某种技术。

①先建立一个config文件,里面建立一个Springconfiguration的类

package com.it.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

import javax.sql.DataSource;
@Configuration
@ComponentScan("com.it")
public class SpringConfiguration {
    /**
    *建立一个QueryRunner对象
    */
    @Bean("runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }

    /**
     * 建立数据源对象
     */
    @Bean("dataSource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass("com.mysql.jdbc.Driver");
            ds.setJdbcUrl("jdbc:mysql://localhost:3306/fresh?characterEncoding=UTF-8");
            ds.setUser("root");
            ds.setPassword("root");
            return  ds;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

Configuration
 *     做用:指定当前类是一个配置类
 *     细节:当配置类做为AnnotationConfigApplicationContext对象建立的参数时,该注解能够不写

ComponentScan
 *      做用:用于经过注解指定spring在建立容器时要扫描的包
 *      属性:
 *          value:它和basePackages的做用是同样的,都是用于指定建立容器时要扫描的包。
 *                 咱们使用此注解就等同于在xml中配置了:
 *                 <context:component-scan base-package="com.itheima"></context:component-scan>

 Bean
 *      做用:用于把当前方法的返回值做为bean对象存入spring的ioc容器中,该注解只能写在方法上
 *      属性:
 *          name:用于指定bean的id,当不写时,默认值是当前方法的名称
 *      细节:
 *          当咱们使用注解配置方法时,若是方法有参数,spring框架会去容器中查找有没有可用的bean对象。
 *          查找的方式和Autowired注解的做用是同样的

②测试类文件中的改写

package com.it;

import com.it.config.SpringConfiguration;
import com.it.entity.Student;
import com.it.service.StudentService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class TestClient {
    @Test
    public  void findAll(){
        //ApplicationContext ac= new ClassPathXmlApplicationContext("ApplicationContext.xml");
        ApplicationContext ac= new AnnotationConfigApplicationContext(SpringConfiguration.class);
        StudentService as = ac.getBean("studentService",StudentService.class);
        List<Student> studentList =as.findAllStudent();
        for (Student student:studentList) {
            System.out.println(student);
        }
    }
}

测试结果以下:

问题来了,上面划线的部分两个的做用是同样的嘛?效果是不同的,下面划线部分,当把对象建立好了后,会把对象给你丢到Spring Ioc容器中,上面划线的部分固然不会那么作,它只是会给你返回一个QueryRunner的对象,这个时候就须要咱们手动把对象丢到容器里面去,就须要采用@Bean的方法

QueryRunner对象是否是一个单例对象

线面还有一个问题就是咱们的QueryRunner对象是否是一个单例对象啦?这个问题关系到咱们线程的问题

那怎么改变bean的做用范围啦?这个是时候寄须要用的scope属性啦,结果以下

父配置类导入子配置类用@Import

对于配置类咱们想要把SpringConfiguration中的jbdc配置专门提取到一个配置类中去?这样的话也方便后期的管理和修改

单元测试findAll的测试结果以下

导入配置perproties配置文件@PropertySource
 *      做用:用于指定properties文件的位置
 *      属性:
 *          value:指定文件的名称和路径。
 *                  关键字:classpath,表示类路径下
 *

在以前JdbcConfig配置类中dataSource的全部的属性都是写死的后来咱们进行了以下改造

package com.it.config;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;

import javax.sql.DataSource;

public class JbdcConfig {
    /**
     * 建立dataSource对象
     * @param dataSource
     * @return
     */
    @Value("${jdbc.driver}")
    private  String driver;
    @Value("${jdbc.url}")
    private  String url;
    @Value("${jdbc.username}")
    private  String username;
    @Value("${jdbc.password}")
    private  String password;

    @Bean("runner")
    @Scope("prototype")
    public QueryRunner createQueryRunner(DataSource dataSource) {
        return new QueryRunner(dataSource);
    }

    /**
     * 建立数据源对象
     */
    @Bean("dataSource")
    public DataSource createDataSource() {
        try {
            ComboPooledDataSource ds = new ComboPooledDataSource();
            ds.setDriverClass(driver);
            ds.setJdbcUrl(url);
            ds.setUser(username);
            ds.setPassword(password);
            return  ds;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

对于新建立的private String driver属性,咱们使用@Valeue("${jdbc.diver}")来注入perproties中的值,在SpringConfigruation配置父类中使用@PropertySource来注入配置文件

测试结果以下,同样能查询到结果

那么咱们通常适合用那种配置方式?用注解仍是,xml啦?

用到已经写好的jar的,通常状况下咱们用xml来配置,比较省事,要是这个类是咱们本身写的话,用注解来配置比较方便

四、Spring和Junit的整合

在咱们的测试类中存在不少的重复的方法,那么有没方法解决啦!!我先采用init的方式先加载建立容器的方式

结果显示没有任何问题,那么这个问题被完全解决掉了嘛?

根据分析获得,junit运行原理

使用Junit单元测试:测试咱们的配置,Spring整合junit的配置
一、导入spring整合junit的jar:spring-test(坐标)
二、使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的@Runwith
三、告知spring的运行器,spring和ioc建立是基于xml仍是注解的,而且说明位置
@ContextConfiguration
属性:locations:指定xml文件的位置,加上classpath关键字,表示在类路径下
          classes:指定注解类所在地位置
细节:当咱们使用spring 5.x版本的时候,要求junit的jar必须是4.12及以上

package com.it;

import com.it.config.SpringConfiguration;
import com.it.entity.Student;
import com.it.service.StudentService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfiguration.class)
public class TestClient {
    @Autowired
    private  StudentService as;
    @Test
    public  void findAll(){
        List<Student> studentList =as.findAllStudent();
        for (Student student:studentList) {
            System.out.println(student);
        }
    }

    @Test
    public  void findbyidtest() {
        //ApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        Student student = as.findByid(4);
        System.out.println(student);
    }

    @Test
    public  void saveTest() {
        Student student=new Student();
        student.setId(7);
        student.setStuno("10007");
        student.setName("陈多糖");
        student.setClassid(2);
        as.saveStudent(student);
    }
    @Test
    public  void updatetest() {
        Student student = as.findByid(4);
        student.setName("陈柳柳");
        as.updateStudent(student);
    }

    @Test
    public  void deletetest() {
        ApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        StudentService as = ac.getBean("studentService", StudentService.class);
        as.deleteStudent(7);
    }
}

测试结果以下:

为何 不把测试类配到 xml 

在解释这个问题以前,先解除你们的疑虑,配到 XML 中能不能用呢? 答案是确定的,没问题,可使用。 那么为何不采用配置到 xml 中的方式呢? 这个缘由是这样的: 第一:当咱们在 xml 中配置了一个 bean,spring 加载配置文件建立容器时,就会建立对象。 第二:测试类只是咱们在测试功能时使用,而在项目中它并不参与程序逻辑,也不会解决需求上的问 题,因此建立完了,并无使用。那么存在容器中就会形成资源的浪费。 因此,基于以上两点,咱们不该该把测试配置到 xml 文件中。

相关文章
相关标签/搜索