• Java框架(三)--Spring IoC容器与Bean管理(8)--基于Java Config配置IoC容器及Spring Test测试模块


    基于Java Config配置IoC容器

    基于Java Config的优势

    完全摆脱XML的束缚,使用独立Java类管理对象与依赖。
    注解配置相对分散,利用Java Config可对配置集中管理。
    可以在编译时进行依赖检查,不容易出错。

    Java Config核心注解

    在这里插入图片描述
    打开IDEA创建新的maven工程,在pom.xml引入Spring依赖

    <?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.ql.spring</groupId>
        <artifactId>ioc_java_config</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <properties>
            <maven.compiler.source>8</maven.compiler.source>
            <maven.compiler.target>8</maven.compiler.target>
        </properties>
        <repositories>
            <repository>
                <id>aliyun</id>
                <name>aliyun</name>
                <url>https://maven.aliyun.com/repository/public</url>
            </repository>
        </repositories>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
        </dependencies>
    </project>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在com.ql.spring.ioc.dao包下创建UserDao类

    package com.ql.spring.ioc.dao;
    
    public class UserDao {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    在com.ql.spring.ioc.service包下创建UserService类

    package com.ql.spring.ioc.service;
    
    import com.ql.spring.ioc.dao.UserDao;
    
    public class UserService {
        private UserDao userDao;
    
        public UserDao getUserDao() {
            return userDao;
        }
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在com.ql.spring.ioc.controller包下创建UserController类

    package com.ql.spring.ioc.controller;
    
    import com.ql.spring.ioc.service.UserService;
    
    public class UserController {
        private UserService userService;
    
        public UserService getUserService() {
            return userService;
        }
    
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在com.ql.spring.ioc包下创建Java Config配置文件Config类

    package com.ql.spring.ioc;
    
    import com.ql.spring.ioc.controller.UserController;
    import com.ql.spring.ioc.dao.UserDao;
    import com.ql.spring.ioc.service.UserService;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration//当前类是一个配置类,用于替代applicationContext.xml
    public class Config {
        @Bean//Java Config利用方法创建对象,将方法返回对象放入容器,beanId = 方法名
        public UserDao userDao(){
            UserDao userDao = new UserDao();
            return userDao;
        }
        @Bean
        public UserService userService(){
            UserService userService = new UserService();
            return userService;
        }
        @Bean//<bean id="xxx" class="xxx">
        public UserController userController(){
            UserController userController = new UserController();
            return userController;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在com.ql.spring.ioc包下创建入口类SpringApplication并运行

    package com.ql.spring.ioc;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class SpringApplication {
        public static void main(String[] args) {
            //基于Java Config配置IoC容器的初始化
            ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
    
            String[] ids = context.getBeanDefinitionNames();
            for(String id: ids){
                System.out.println(id+":"+context.getBean(id));
            }
        }
    }
    /*
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor:org.springframework.context.annotation.ConfigurationClassPostProcessor@f0f2775
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@5a4aa2f2
    org.springframework.context.annotation.internalCommonAnnotationProcessor:org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@6591f517
    org.springframework.context.event.internalEventListenerProcessor:org.springframework.context.event.EventListenerMethodProcessor@345965f2
    org.springframework.context.event.internalEventListenerFactory:org.springframework.context.event.DefaultEventListenerFactory@429bd883
    config:com.ql.spring.ioc.Config$$EnhancerBySpringCGLIB$$56178750@4d49af10
    userDao:com.ql.spring.ioc.dao.UserDao@279ad2e3
    userService:com.ql.spring.ioc.service.UserService@58134517
    userController:com.ql.spring.ioc.controller.UserController@4450d156
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    下面再看看Java Config其他配置:
    在com.ql.spring.ioc.dao包下创建EmployeeDao类

    package com.ql.spring.ioc.dao;
    
    import org.springframework.stereotype.Repository;
    
    @Repository
    public class EmployeeDao {
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    然后修改UserService

    package com.ql.spring.ioc.service;
    
    import com.ql.spring.ioc.dao.EmployeeDao;
    import com.ql.spring.ioc.dao.UserDao;
    
    public class UserService {
        private UserDao userDao;
        private EmployeeDao employeeDao;
    
        public UserDao getUserDao() {
            return userDao;
        }
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public EmployeeDao getEmployeeDao() {
            return employeeDao;
        }
    
        public void setEmployeeDao(EmployeeDao employeeDao) {
            this.employeeDao = employeeDao;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    修改Config类

    package com.ql.spring.ioc;
    
    import com.ql.spring.ioc.controller.UserController;
    import com.ql.spring.ioc.dao.EmployeeDao;
    import com.ql.spring.ioc.dao.UserDao;
    import com.ql.spring.ioc.service.UserService;
    import org.springframework.context.annotation.*;
    
    @Configuration//当前类是一个配置类,用于替代applicationContext.xml
    @ComponentScan(basePackages = "com.ql")//兼容注解配置,相当于XML的 context:component-scan
    public class Config {
        @Bean//Java Config利用方法创建对象,将方法返回对象放入容器,beanId = 方法名
        public UserDao userDao(){
            UserDao userDao = new UserDao();
            System.out.println("已创建"+userDao);
            return userDao;
        }
        @Bean//Java Config利用方法创建对象,将方法返回对象放入容器,beanId = 方法名
        @Primary
        public UserDao userDao1(){
            UserDao userDao = new UserDao();
            System.out.println("已创建"+userDao);
            return userDao;
        }
        @Bean
        //先按name尝试注入,name不存在则按类型注入
        public UserService userService(UserDao udao, EmployeeDao employeeDao){
            UserService userService = new UserService();
            System.out.println("已创建"+userService);
            userService.setUserDao(udao);
            System.out.println("调用setUserDao:"+udao);
            userService.setEmployeeDao(employeeDao);
            return userService;
        }
        @Bean//<bean id="xxx" class="xxx">
        @Scope("prototype")
        public UserController userController(UserService userService){
            UserController userController = new UserController();
            System.out.println("已创建"+userController);
            userController.setUserService(userService);
            System.out.println("调用setUserService:"+userService);
            return userController;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    修改入口类SpringApplication并运行

    package com.ql.spring.ioc;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    public class SpringApplication {
        public static void main(String[] args) {
            //基于Java Config配置IoC容器的初始化
            ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
            System.out.println("========================");
            String[] ids = context.getBeanDefinitionNames();
            for(String id: ids){
                System.out.println(id+":"+context.getBean(id));
            }
        }
    }
    /*
    已创建com.ql.spring.ioc.dao.UserDao@29ba4338
    已创建com.ql.spring.ioc.dao.UserDao@7bb58ca3
    已创建com.ql.spring.ioc.service.UserService@36f0f1be
    调用setUserDao:com.ql.spring.ioc.dao.UserDao@7bb58ca3
    ========================
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor:org.springframework.context.annotation.ConfigurationClassPostProcessor@e50a6f6
    org.springframework.context.annotation.internalAutowiredAnnotationProcessor:org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@14ec4505
    org.springframework.context.annotation.internalCommonAnnotationProcessor:org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@53ca01a2
    org.springframework.context.event.internalEventListenerProcessor:org.springframework.context.event.EventListenerMethodProcessor@358c99f5
    org.springframework.context.event.internalEventListenerFactory:org.springframework.context.event.DefaultEventListenerFactory@3ee0fea4
    config:com.ql.spring.ioc.Config$$EnhancerBySpringCGLIB$$93bfe412@48524010
    employeeDao:com.ql.spring.ioc.dao.EmployeeDao@4b168fa9
    userDao:com.ql.spring.ioc.dao.UserDao@29ba4338
    userDao1:com.ql.spring.ioc.dao.UserDao@7bb58ca3
    userService:com.ql.spring.ioc.service.UserService@36f0f1be
    已创建com.ql.spring.ioc.controller.UserController@55a561cf
    调用setUserService:com.ql.spring.ioc.service.UserService@36f0f1be
    userController:com.ql.spring.ioc.controller.UserController@55a561cf
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    从运行结果看出:UserController 配置为多例模式,没有随着IcC初始化。EmployeeDao用注解配置成功,并成功注入到UserService类。

    Spring Test测试模块

    Spring Test是Spring中用于测试的模块。
    Spring Test对JUnit单元测试框架有良好的整合。
    通过Spring Test可在JUnit在单元测试时自动初始化IoC容器。

    Spring与JUnit4整合过程

    Maven工程依赖spring-test

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    修改UserDao和UserService类

    package com.ql.spring.ioc.dao;
    
    public class UserDao {
        public void insert(){
            System.out.println("新增用户数据");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    package com.ql.spring.ioc.service;
    
    import com.ql.spring.ioc.dao.EmployeeDao;
    import com.ql.spring.ioc.dao.UserDao;
    
    public class UserService {
        private UserDao userDao;
        private EmployeeDao employeeDao;
    
        public void createUser(){
            System.out.println("调用创建用户业务代码");
            userDao.insert();
        }
        public UserDao getUserDao() {
            return userDao;
        }
    
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
        public EmployeeDao getEmployeeDao() {
            return employeeDao;
        }
    
        public void setEmployeeDao(EmployeeDao employeeDao) {
            this.employeeDao = employeeDao;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    利用**@RunWith@ContextConfiguration**描述测试用例类。
    测试用例类从容器获取对象完成测试用例的执行。

    import com.ql.spring.ioc.Config;
    import com.ql.spring.ioc.service.UserService;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.springframework.test.context.ContextConfiguration;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    
    import javax.annotation.Resource;
    
    //将Junit4的执行权交由Spring Test,在测试用例执行前自动初始化IoC容器
    @RunWith(SpringJUnit4ClassRunner.class)
    //@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
    @ContextConfiguration(classes = Config.class)
    public class SpringTestor {
        @Resource
        private UserService userService;
    
        @Test
        public void testUserService(){
            userService.createUser();
        }
    }
    /*
    已创建com.ql.spring.ioc.dao.UserDao@4cc451f2
    已创建com.ql.spring.ioc.dao.UserDao@294425a7
    已创建com.ql.spring.ioc.service.UserService@595b007d
    调用setUserDao:com.ql.spring.ioc.dao.UserDao@294425a7
    调用创建用户业务代码
    新增用户数据
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
  • 相关阅读:
    Unity中Shader的扭曲(不是UV的扭曲)
    Linux docker 搭建Redis主从复制集群、新增(扩容)主/从节点、删除(缩容)主/从节点
    【笔记篇】11仓管系统WCS系统——之《实战供应链》
    在Docker中运行PostgreSQL数据库
    【电商】电商后台设计—购物车
    拼多多无货源商品数据API接口
    每秒生成10万订单号
    如何理解发明和实用新型具备的实用性?
    26.Xaml Menu控件---->菜单控件 (手动创建菜单,命令,Icon,快捷键)
    LeetCode高频题34. 在排序数组中查找元素的第一个和最后一个位置
  • 原文地址:https://blog.csdn.net/qq_32091929/article/details/125578736