• Spring-IOC案例及单元测试


    Spring-IOC案例的两种配置,xml 配置,和注解配置

    一:使用 xml 配置链接数据库

    <!--配置Service    -->
        <bean id="userService" class="huarangmeng.service.impl.UserServiceImpl">
            <!--注入Dao对象        -->
            <property name="userDao" ref="userDao"></property>
        </bean>
    
        <!--配置Dao    -->
        <bean id="userDao" class="huarangmeng.dao.impl.UserDaoImpl">
            <!--注入QueryRunner        -->
            <property name="runner" ref="runner"></property>
        </bean>
    
        <!--配置QueryRunner    -->
        <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/test"></property>
            <property name="user" value="test"></property>
            <property name="password" value="a123456789"></property>
        </bean>
    

    二:通过注解配置

    QueryRunner为jar包中的字节码,无法直接通过注解配置

    数据源同样

    因而需要一个注解类来解决

    /**
     * 该类是一个配置类,它的作用和bean.xml是一样的
     * spring中的新注解
     * @Configuration
     *      作用:指定当前类是一个配置类
     *      细节:当配置类作为AnnotationConfigApplicationContext对象创建的参数时,该注解可以不写
     * @ComponentScan
     *      作用:用于通过注解指定spring在创建容器时要扫描的包
     *      属性:
     *          value:他和basePackages的作用时一样的,都是用于指定创建容器时要扫描的包
     *              我们使用此注解就等同于在xml中配置了
     *              <context:component-scan base-package="huarangmeng"></context:component-scan>
     * @Bean
     *      作用:用于把当前方法的返回值作为bean对象存入spring的IOC容器中
     *      属性:
     *          name:用于指定 bean 的 id。默认值为 当前方法的名称.
     *      细节:当我们使用注解配置方法时,如果方法有参数,spring框架会去容器中查找是否有可用的bean对象
     *            查找的方式与 @Autowired注解的作用相同
     * @Import
     *      作用:用于导入其他的配置类
     *      属性:value:用于指定其他配置类的字节码。
     *      当我们使用 @Import注解后,有@Import注解的类就是父类配置,而导入的就是子配置类
     *
     * @PropertySource
     *      作用:用于指定properties文件的位置
     *      属性:
     *          value:指定文件的名称和路径
     *          关键字:classpath:表示类路径
     */
    @Configuration
    //@ComponentScan(basePackages = {"huarangmeng"}) 两种都可以
    @ComponentScan("huarangmeng")
    @Import(JdbcConfig.class)
    @PropertySource("classpath:jdbc.properties")
    public class SpringConfiguration {
    
        @Value("${jdbc.driver}")
        private String driver;
    
        @Value("${jdbc.url}")
        private String url;
    
        @Value("${jdbc.username}")
        private String username;
    
        @Value("${jdbc.password}")
        private String password;
    
        /**
         * 用于创建一个QueryRunner对象
         * @param dataSource
         * @return
         */
        @Bean(name = "runner")
        @Scope("prototype")
        public QueryRunner creteQueryRunner(DataSource dataSource){
            return new QueryRunner(dataSource);
        }
    
        /**
         * 创建数据源对象
         * @return
         */
        @Bean(name = "dataSource")
        public DataSource creteDataSource(){
            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);
            }
        }
    }
    

    举例说明 @Configuration 和 @ComponentScan,引入@Import 注解

    1. 当配置类作为 AnnotationConfigApplicationContext 对象创建的参数时,@Configuration注解可以不写

    倘若有两个配置类,分别为 SpringConfiguration.class 和 JdbcConfig.class,直接作为参数,可不使用@Configuration注解,两个类可当作兄弟关系

    //1.获取容器
    ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class,JdbcConfig.class);
    //2.得到业务层对象
    IUserService us = ac.getBean("userService", IUserService.class);
            
    // JdbcConfig注解类
    public class JdbcConfig {
    }
    // SpringConfiguration注解类
    public class SpringConfiguration {
    }
    
    1. 希望 SpringConfiguration.class 和 JdbcConfig.class 作为父子关系时

      //1.获取容器
      ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
      //2.得到业务层对象
      IUserService us = ac.getBean("userService", IUserService.class);
              
      // 第一种做法,给JdbcConfig类添加 @Configuration注解
      //给SpringConfiguration中添加扫描JdbcConfig的注解
      @Configuration
      public class JdbcConfig {
      }
      // SpringConfiguration注解类
      @ComponentScan("huarangmeng")
      public class SpringConfiguration {
      }
      		
      //第二种做法,给SpringConfiguration中添加@Import注解
      public class JdbcConfig {
      }
      // SpringConfiguration注解类
      @Import(JdbcConfig.class)
      public class SpringConfiguration {
      }
      

      三:Spring中的单元测试

      直接使用JUnit进行单元测试,存在问题,以下第一步和第二步,每个测试方法都要写,且要求测试同学有学过spring才会写出相应的代码

          @Test
          public void testFindAll(){
              //1.获取容器
      //        ApplicationContext ac = new ClassPathXmlApplicationContext("dao.xml");
      
              ApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
              //2.得到业务层对象
              IUserService us = ac.getBean("userService", IUserService.class);
              //3.执行方法
              List<User> users = us.findAllUser();
              for (User user: users) {
                  System.out.println(user);
              }
          }
      

      解决每个测试方法都要写前两步的问题

          private ApplicationContext ac;
      
          private IUserService us;
      
          @Before
          public void init(){
      //        1.获取容器
      //        ApplicationContext ac = new ClassPathXmlApplicationContext("dao.xml");
      
              ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
      //        2.得到业务层对象
              us = ac.getBean("userService", IUserService.class);
          }
      
          @Test
          public void testFindAll(){
              //3.执行方法
              List<User> users = us.findAllUser();
              for (User user: users) {
                  System.out.println(user);
              }
          }
      

      仍然存在相应的代码需要写,则使用spring-test包解决问题

      为什么不能直接使用注解注入 IUserService,原因是 JUnit 下没有spring的IOC容器

      /**
       * 使用JUnit单元测试,测试我们的配置
       * spring整合junit配置
       *      1.导入spring整合junit的jar包
       *      2.使用Junit提供的一个注解把原有的main方法替换了,替换成spring提供的
       *          @RunWith
       *      3.告知spring 的运行期,spring的IOC容器创建时基于 xml 还是注解的,并说明位置
       *          @ContextConfiguration
       *              location:指定xml文件的位置,加上classpath关键字,表示在类路径下
       *              classes:指定注解类所在的位置
       *   当我们使用spring 5.X版本时,要求Junit的jar版本必须是4.12及以上
       */
      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes = SpringConfiguration.class)
      public class UserServiceTest {
      
          @Autowired
          private IUserService us;
      
          @Test
          public void testFindAll(){
              //3.执行方法
              List<User> users = us.findAllUser();
              for (User user: users) {
                  System.out.println(user);
              }
          }
      }
      
  • 相关阅读:
    深度学习之 TensorFlow(一):基础库包的安装
    爬取网易云音乐评论并使用词云展示
    MySQL学习笔记(一):查询
    【linux】查看linux系统版本信息(Oracle Linux、Centos Linux、Redhat Linux、Debian、Ubuntu)
    【php】PHP中Session ID的实现原理
    VMware安装VMwareTolls
    退耦、旁路电容
    SPI笔记
    旧板与IO板之间的连接
    S3C2440启动方式
  • 原文地址:https://www.cnblogs.com/huaranmeng/p/13680580.html
Copyright © 2020-2023  润新知