SpringIoC和DI注解开发

今日内容:

  1. 注解

    使用注解替代配置文件, 简化书写

  2. 案例

    spring整合junit, spring整合mybatis.

  3. AOP

    AOP底层原理,简单使用一下

1.什么是注解驱动

  • 注解概述

    注解启动时使用注解的形式替代xml配置,将繁杂的spring配置文件从工程中彻底消除掉,简化书写

  • 缺点

    1. 为了达成注解驱动的目的,可能会将原先很简单的书写,变的更加复杂
    2. XML中配置第三方开发的资源是很方便的,但使用注解驱动无法在第三方开发的资源中进行编辑,因此会增大开发工作量

比如: 自定义的类, 可以在类上加上注解,通过扫描注解,初始化该类,存到容器中.

比如: 项目中引入第三方的依赖, 要想让第三方的依赖的类, 交给spring容器来管理.需要定义一个方法,返回该对象,在方法上面加上@Bean

如图:

在这里插入图片描述

2. Spring注解开发:

注意: Spring注解开发, 通过注解初始化bean对象,或者给bean的属性赋值

2.1 注解开发使用步骤

  • 步骤一: 创建spring的配置类,替代配置文件,启动注解扫描,加载类中配置的注解项

    /**
     * 创建一个spring的配置类,这个类的作用就是替代spring的配置文件
     * @Configuration: 指定该类是 一个配置类
     * @ComponentScan("com.service.impl"): 指定扫描的包
     */
    @ComponentScan("com.service.impl")
    @Configuration
    public class SpringConfiguration {
    }
    
    

    当然,如果使用配置文件的话

    <?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
           https://www.springframework.org/schema/context/spring-context.xsd">
    <!--
       spring容器扫描注解:
       通过扫描带注解的类的所在的包, 扫描带注解的类,初始化bean对象,存到容器中
       配置扫描包的书写格式:
       1. base-package="com.dao,com.service,com.web", 扫描com下的dao,service,web包
       2.base-package="com", 扫描com包以及com下面所有子包
    -->
       <context:component-scan base-package="com.service.impl"></context:component-scan>
    </beans>
    
  • 步骤二: 在所在包以及子包下面的类上面, 加上bean注解

    /**
     * @Component注解作用: 定义在类上,
     * 通过spring扫描机制,如果扫描到带@Component注解的类,
     * 那么就会初始化bean( DeptServiceImpl),存到容器里面(1.根据名称存,2,根据类型存储)
     */
    @Component
    public class DeptServiceImpl implements DeptService {
        @Override
        public void addOne(){
            System.out.println("执行部门的添加方法11111");
        }
    }
    

    测试代码:

    public class Demo {
        @Test
        public void testX3(){
            //1.创建注解容器,加载配置文件
            BeanFactory bf = new AnnotationConfigApplicationContext(SpringConfiguration.class);
            //2.根据名称(根据id的属性值)获取bean对象
            DeptServiceImpl bean = (DeptServiceImpl) bf.getBean("deptServiceImpl");
            bean.addOne();
        }
        @Test
        public void testX2(){
            //1.创建注解容器,加载配置文件
            BeanFactory bf = new AnnotationConfigApplicationContext(SpringConfiguration.class);
            //2.获取bean对象
            DeptServiceImpl bean = bf.getBean(DeptServiceImpl.class);
            bean.addOne();
        }
        @Test
        public void testX(){
            //1.创建容器,加载配置文件
            BeanFactory bf = new ClassPathXmlApplicationContext("applicaitonContext.xml");
            DeptServiceImpl bean = bf.getBean(DeptServiceImpl.class);
             bean.addOne();
        }
    }
    
    

    小结说明:

    ◆ 在进行包所扫描时,会对配置的包及其子包中所有文件进行扫描

    ◆ 扫描过程是以文件夹(包结构其实就是文件夹)递归迭代的形式进行的

    ◆ 扫描过程仅读取合法的java文件

    ​ 对带注解的java类进行初始化, 初始化存到容器里面

    ​ (常见1.根据名称存储(默认名称是类名的小驼峰命名法) 2. 根据class来存储)

    ◆ 扫描结束后会将可识别的有效注解转化为spring对应的资源加入IoC容器

    注意:

    ◆ 无论是注解格式还是XML配置格式,最终都是将资源加载到IoC容器中,差别仅仅是数据读取方式不同

    ◆ 从加载效率上来说注解优于XML配置文件

  • 模拟spring容器基于注解开发,初始化bean对象,存到容器中.

    • 步骤一: 定义注解 @MyComponent, @MyConfiguration

      @Target(ElementType.TYPE)//限定注解的作用位置, 在类上上面
      @Retention(RetentionPolicy.RUNTIME)//指定注解的保留时长,设置注解一直活到运行时
      public @interface MyComponent {
          String value() default "";//指定bean的名称
      }
      
      @Target(ElementType.TYPE)//限定注解的作用位置, 在类上上面
      @Retention(RetentionPolicy.RUNTIME)//指定注解的保留时长,设置注解一直活到运行时
      public @interface MyConfiguration {//注解类: 作用配置扫描的包
          String value();//配置扫描的包
          //String[] value();
          //String[] basePackages();
      }
      
      
    • 步骤二: 定义一个测试类, 类上面加上自定义的注解@MyComponent

      @MyConfiguration("system.my.bean")
      public class MySpringConfig {//定义配置类
      }
      
      //使用自定义的注解,通过value属性设置bean的名称
      @MyComponent("demoService")
      public class DemoService {//定义一个bean类测试
          public  void testService(){
              System.out.println("执行业务层的方法");
          }
      }
      
      
    • 步骤三: 自定义注解的容器对象: 1. 引入配置类,读取配置类上面扫描的包 2. 递归调用包文件夹,获取java类

      
      /**
       * 在进行包所扫描时,会对配置的包及其子包中所有文件进行扫描
       * ◆ 扫描过程是以文件夹(包结构其实就是文件夹)递归迭代的形式进行的
       * ◆ 扫描过程仅读取合法的java文件
       * ​ 对带注解的java类进行初始化, 初始化存到容器里面(常见1.根据名称存储  2. 根据class来存储)
       * ◆ 扫描结束后会将可识别的有效注解转化为spring对应的资源加入IoC容器
       */
      public class MyAnnotationContainer {
          //0.定义容器
          //map的key: bean的名称或者bean的class对象
          //map的value: bean的对象
          private Map<Object,Object> container = new ConcurrentHashMap<Object,Object>();
          //1.引入注解的配置类
          private Class configClass;
          //2.通过构造方法给注解的配置类赋值
          public MyAnnotationContainer(Class configClass){
              //3.给配置类赋值
              this.configClass = configClass;//MySpringConfig
              //4.通过配置类,获取配置注解 MySpringConfig
              boolean flag = configClass.isAnnotationPresent(MyConfiguration.class);
              if(flag){
                  //说明MySpringConfig类上面有注解: MyConfiguration
                  MyConfiguration annotation =(MyConfiguration)
                          configClass.getAnnotation(MyConfiguration.class);
                  //获取MyConfiguration配置的包
                  String packageName = annotation.value();//system.my.bean.son
                  //递归调用包里面的所有的java文件,获取到包下面的所有类,判断类上面是否有 MyComponent
                  scanAnnotationCreateBeanTOMpa(packageName);
              }
      
          }
          //定义一个方法: 获取包下面的所有类,判断类上面是否有注解 MyComponent ,如果有初始bean,存到容器中
          public  void  scanAnnotationCreateBeanTOMpa(String packageName){
              //1.解析包.//修改包结构变成文件夹system/my/bean/son
              String packagePathName= packageName.replace(".","/");
              try {
                  //2.通过类加载器获取包的绝对路径(带盘符的)
                  Enumeration<URL> resources =  MyAnnotationContainer.class.getClassLoader().getResources(packagePathName);
                  //3.获取包下面的所有java文件: class文件
                  Set<String>  classNames=null;
                  while (resources.hasMoreElements()){
                      URL url = resources.nextElement();//拿到枚举类里面保存的文件的绝对路径
                      String filePath = url.getFile();
                      classNames = FileUtils.getAllFilesName(new File(filePath));
                  }
                  //4.根据class文件,创建bean对象,存到容器中
                  if(classNames!=null && classNames.size()>0){
                      //5.判断bean是否带有MyComponent
                      for (String className : classNames) {
                            //className: DemoMapper.class,DemoService.clas
                          // 截取class,获取类名DemoMapper,DemoMapper
                          String typeName= className.substring(0,className.lastIndexOf("."));
                         //拼接类的全路径: 包名+类名
                          String typeAllName = packageName+"."+typeName;
                          //利用反射: 得到Class
                          Class clz = Class.forName(typeAllName);
                          //判断该类上面是否有MyComponent
                          //DemoMapper, DemoService上面是有注解MyComponent
                          boolean flag = clz.isAnnotationPresent(MyComponent.class);
                          if(flag){
                              //获取类上面的注解对象
                              MyComponent myComponent =(MyComponent) clz.getAnnotation(MyComponent.class);
                              //获取注解里面配置的bean的名称
                              String beanName = myComponent.value();
                              //利用无参数的构造方法创建bean对象
                              Object beanObj = clz.newInstance();
                              //根据名称添加到容器中
                              container.put(beanName,beanObj);
                              //根据类型存添加到容器中
                              container.put(clz,beanObj);
                          }
      
                      }
                  }
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
          //3.根据名称从容器中获取bean对象
          public  Object  getBeanForName(String name){
              return  container.get(name);
          }
          //4.根据class类型,从容器中获取bean对象
          public <T> T getBeanForClass(Class<T> clz){
              Object o = container.get(clz);
              T bean = (T) o;
              return bean;
          }
          
      }
      
      

2.2 引用类型注解: 自定义类被初始化bean对象的注解

  • 自定义bean类,初始化对象的注解

    注解名称:@Component, @Controller, @Service ,@Repository

在这里插入图片描述

小结:

  1. 上面的注解是作用在自定义的类上面, 容器通过扫描注解初始化bean对象存到容器中

    • 方式一: 根据类的class类型,存储bean对象

    • 方式二: 如果在上面的注解里面没有给名称, 根据类名的小驼峰命名规则,存储bean对象.

      ​ 比如: 自定义类UserController,@Controller如果没有赋值, 那么容器中存的名称: userController(小驼峰)

  • bean的作用域的注解

    注解名称 @Scope

    如图:

在这里插入图片描述

小结:

指定bean对象的作用范围,常用的取值: singleton, prototype

  • @Scope("singleton"): bean对象是在初始化容器对象时,bean对象已经创建了,可以理解为立即加载
    
  • @Scope("prototype"): bean对象在获取时,才创建, 可以理解为懒加载
    
  • bean的生命周期的注解

    注解的名称@PostConstruct @PreDestroy

在这里插入图片描述

2.3 引用类型注解: 加载第三方资源, 一般是第三方框架里面bean类,

注解名称为@Bean
在这里插入图片描述


public class DataSourceConfig {
    //@Bean注解,仅仅表示作用与第三方的类.要想该bean存到容器中,需要在配置类导入
    @Bean("druidDataSource")
    public DataSource  createDataSource(){
        //1.创建连接池对象
        DruidDataSource ds = new DruidDataSource();
        //2.设置最基本的四个连接参数
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql:///db12");
        ds.setUsername("root");
        ds.setPassword("root");
        return  ds;
    }
}

@Configuration
//@ComponentScan("three_bean")//第三方类不需要被扫描
@Import({DataSourceConfig.class})
public class SpringConfig333 {
}

public class DemoThree {
    public static void main(String[] args) throws Exception{
        BeanFactory bc = new AnnotationConfigApplicationContext(SpringConfig333.class);
        DataSource druidDataSource =(DataSource)bc.getBean("druidDataSource");
        System.out.println(druidDataSource.getConnection());
    }
}

注意: 第三方资源如果被其它地方引用, 需要添加value属性,指定bean的名称, 或者使用class对象从容器中获取

小结:

  1. 如果是第三方的类(不是自定义的类), 需要定义一个方法获取第三方的bean对象,在该方法上面加上@Bean
  2. 需要通过**@Import({第三方的类的class对象})**导入到配置类上面
  3. 注意: 第三方的类一般需要包扫描.

2.4 非引用类型属性注入(简单类型注入:基本类型,数组类型,集合类型,Properties类型)

注解的名称为@Value

如图
在这里插入图片描述

小结:

@Value注解给bean中的简单类型(基本类型, 数组类型,集合类型,Properties类型)赋值

赋值方式有两种:

  • 方式一: 可以直接赋值: 比如:
    在这里插入图片描述

  • 方式二: 通过@PropertySource引入外部的数据源文件(文件类型是properties),可以通过spel表达式获取值

    使用要求:

    1. 文件类型必须是properties
    2. 文件必须放在类路径下面.
    • outer.properties

      key=A001111111
      
    • @PropertySource类中引入:

      /**
       * @Component用在定义类的上面
       * 存到容器里面,默认名称是: demoDI
       * @PropertySource作用: 引入外部的配置文件,外部的配置文件放在类路径下面
       */
      @Component
      @Data
      @PropertySource("classpath:outer.properties")
      public class DemoDI {
          // @Value("A001")
          @Value("${key}")
          private   String uid;
      
      }
      
      

2.5 引用类型属性注入

  • 引用类型属性注入概述

    指的在一个bean对象中,注入另一个bean对象.

    注入方式有两种(可以通过配置文件配置):

    方式一: 可以通过set方法注入

    方式二: 可以通过有参构造方法注入

实现方式有两种

  • 方式一: @Autowired(可以单独使用)、@Qualifier(不能单独使用,必须配合Autowired使用)

    代码如下:

    第一步: 在容器对象初始化时, 会将AService对象初始化,存到容器中

    @Service("aService")
    public class AService {
        public  void  findAll(){
            System.out.println("执行业务层查询所有操作");
        }
    }
    
    

    第二步: 将AService注入到AController类里面, 通过@Autowired. 默认是根据class从容器获取bean.

    @Controller
    public class AController {
        //需求: 在业务层, 创建ADao对象, 调用查询方法
        //private ADao dao = new ADao();不推荐使用
        //默认根据class字节码对象从容器中获取 AService对象, 通过set方法给成员变量service赋值
        @Autowired
        @Qualifier("aService")
        private  AService service;
    
        public void list(){
    
            service.findAll();
        }
    
    }
    
    

    第三步: 测试

        public static void main(String[] args){
            //1.自定义类, 加上了@Controller,@Service,默认创建化容器对象以后,就会初始化自定义类,存到容器中
            BeanFactory bc = new AnnotationConfigApplicationContext(SpringConfig444.class);
            //2.根据类型从容器中获取AController对象
            /**3.由于AController里面,通过@Autowired, 注入service
             *   默认根据AService的class字节码对象,从容器中拿到AService对象,通过set方法给service变量赋值
             *    @Autowired
             *     private  AService service;
             */
            //4.类中service变量已经通过set方法赋值了
            AController bean = bc.getBean(AController.class);
            bean.list();
        }
    
    
  • 方式二: @Resource,是JSR250(JAVAEE)规范中的注解,可以简化书写格式

    @Resource相关属性

    ◆ name:设置注入的bean的id

    ◆ type:设置注入的bean的类型,接收的参数为Class类型

    小结:

    @Resource作用:

    首先默认根据bean的名称从容器中获取bean对象,通过set方法进行注入.

    如果根据名称找不到容器中的 bean对象, 会根据class对象从容器中获取bean对象,获取完以后,通过set方法进行注入.

  • 方式一和方式二的区别

在这里插入图片描述

扩展:

**JAVAEE也提供了一个注解 @Resource,默认根据名称从容器中取出bean,如果根据名称没有找到bean, **

那么会根据类型去容器中找到bean, 最终注入到类中

  • 细节
    在这里插入图片描述

2.7 其它引用类型注入注解

在这里插入图片描述

3.常用注解

3.1 加载外部的properties注解

在这里插入图片描述

3.2 扫描注解和替代文件注解

注意: 纯注解开发的话, 使用AnnotationConfigApplicationContext 注解容器对象
在这里插入图片描述

3.3 导入第三方Bean的注解

注意: @Import通常和@Configuration一块使用(加上@Configuration目的是被spring扫描到)
在这里插入图片描述

3.4 扩展注解(了解)

  • @DependsOn和@Order注解: 作用可以指定bean对象的加载顺序

  • 应用场景:

    如果功能中需要明确指定bean对象的创建顺序,那么可以使用以上注解.

  • 面试题(中高级程序员): spring框架中bean对象的环绕依赖问题(本质单列不会出现环绕依赖)

    @Component
    @DependsOn("c")
    @Lazy
    public class A {
        @Autowired
        private B b;
        public void testA(){
            b.testB();
            System.out.println("执行A");
        }
    }
    @Component
    @DependsOn("a")
    @Lazy
    public class B {
        @Autowired
        private C c;
        public void testB(){
            System.out.println("执行B---");
        }
    }
    @Component
    @Lazy
    public class C {
        @Autowired
        private A a;
        public void testC(){
            System.out.println("执行C---");
        }
    }
    
    @ComponentScan("com.round_di.bean")
    @Configuration
    @Order(1)
    public class SpringBeanConfig {
    }
    public class Demo {
        public static void main(String[] args){
            BeanFactory bf = new AnnotationConfigApplicationContext(SpringBeanConfig.class);
            A bean = bf.getBean(A.class);
            bean.testA();
        }
    }
    
    

    在这里插入图片描述

  • bean的加载控制
    在这里插入图片描述
    在这里插入图片描述

3.5 Spring注解总结

Spring是轻代码而重配置的框架,配置比较繁重,影响开发效率,所以注解开发是一种趋势,注解代替xml配置文件可以简化配置,提高开发效率。

Spring原始注解, 主要是替代bean标签的配置

注解说明
@Component使用在类上用于实例化Bean
@Controller使用在web层类上用于实例化Bean
@Service使用在service层类上用于实例化Bean
@Repository使用在dao层类上用于实例化Bean
@Autowired使用在字段上用于根据类型依赖注入
@Qualifier结合@Autowired一起使用用于根据名称进行依赖注入
@Resource相当于@Autowired+@Qualifier,默认按照名称进行注入
@Value注入普通属性
@Scope标注Bean的作用范围
@PostConstruct使用在方法上标注该方法是Bean的初始化方法
@PreDestroy使用在方法上标注该方法是Bean的销毁方法
@lazy指定bean对象的创建时机,比如: 在初始化容器时,创建bean对象,或者getBean方法再创建
@PropertySource引入外部的后缀名为properties文件, 文件必须放在类路径下面

注意:

使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法。

<!--注解的组件扫描-->
<context:component-scan base-package="com.tedu"></context:component-scan>

使用@Compont或@Repository标识UserDaoImpl需要Spring进行实例化。

//@Component("userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Override
    public void save() {
    	System.out.println("save running... ...");
    }
}

使用@Compont或@Service标识UserServiceImpl需要Spring进行实例化

使用@Autowired或者@Autowired+@Qulifier或者@Resource进行userDao的注入

//@Component("userService")
@Service("userService")
public class UserServiceImpl implements UserService {
    /*@Autowired
    @Qualifier("userDao")*/
    @Resource(name="userDao")
    private UserDao userDao;
    @Override
    public void save() {       
   	  userDao.save();
    }
}

使用@Value进行字符串的注入

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    @Value("注入普通数据")
    private String str;
    @Value("${jdbc.driver}")
    private String driver;
    @Override
    public void save() {
        System.out.println(str);
        System.out.println(driver);
        System.out.println("save running... ...");
    }
}

使用@Scope标注Bean的范围

//@Scope("prototype")
@Scope("singleton")
public class UserDaoImpl implements UserDao {
   //此处省略代码
}

使用@PostConstruct标注初始化方法,使用@PreDestroy标注销毁方法

@PostConstruct
public void init(){
	System.out.println("初始化方法....");
}
@PreDestroy
public void destroy(){
	System.out.println("销毁方法.....");
}

Spring新注解: 支持纯注解开发

使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:

非自定义的Bean的配置:

加载properties文件的配置:context:property-placeholder

组件扫描的配置:context:component-scan

引入其他文件:

注解说明
@Configuration用于指定当前类是一个 Spring 配置类,当创建容器时会从该类上加载注解
@ComponentScan用于指定 Spring 在初始化容器时要扫描的包。 作用和在 Spring 的 xml 配置文件中的 <context:component-scan base-package=“com.tedu”/>一样
@Bean使用在方法上,标注将该方法的返回值存储到 Spring 容器中
@PropertySource用于加载.properties 文件中的配置
@Import用于导入其他配置类

@Configuration

@ComponentScan

@Import

@Configuration
@ComponentScan("com.tedu")
@Import({DataSourceConfiguration.class})
public class SpringConfiguration {
}

@PropertySource

@value

@PropertySource("classpath:jdbc.properties")
public class DataSourceConfiguration {
    @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

@Bean(name="dataSource")
public DataSource getDataSource() throws PropertyVetoException { 
    ComboPooledDataSource dataSource = new ComboPooledDataSource(); 
    dataSource.setDriverClass(driver);
    dataSource.setJdbcUrl(url);
    dataSource.setUser(username);
    dataSource.setPassword(password);
    return dataSource;
} 

测试加载核心配置类创建Spring容器

@Test
public void testAnnoConfiguration() throws Exception {
ApplicationContext applicationContext = new 
          AnnotationConfigApplicationContext(SpringConfiguration.class);   
    UserService userService = (UserService)    
    applicationContext.getBean("userService");
    userService.save();
    DataSource dataSource = (DataSource) 
    applicationContext.getBean("dataSource");
    Connection connection = dataSource.getConnection(); 
    System.out.println(connection);
    }

4. Spring整合Junit

4.1 原始Junit测试Spring的问题

在测试类中,每个测试方法都有以下两行代码:

 ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
 IAccountService as = ac.getBean("accountService",IAccountService.class);

这两行代码的作用是获取容器,如果不写的话,直接会提示空指针异常。所以又不能轻易删掉。

4.2 上述问题解决思路

让SpringJunit负责创建Spring容器,但是需要将配置文件的名称告诉它

将需要进行测试Bean直接在测试类中进行注入

4.3 Spring集成Junit步骤

①导入spring集成Junit的坐标

②使用@Runwith注解替换原来的运行容器

③使用@ContextConfiguration指定配置文件或配置类

④使用@Autowired注入需要测试的对象

⑤创建测试方法进行测试

4.4 Spring集成Junit代码实现

①导入spring集成Junit的坐标

<!--此处需要注意的是,spring5 及以上版本要求 junit 的版本必须是 4.12 及以上-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.2.RELEASE</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

②使用@Runwith注解替换原来的运行期

@RunWith(SpringJUnit4ClassRunner.class)
public class SpringJunitTest {
}

③使用@ContextConfiguration指定配置文件或配置类

@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}

④使用@Autowired注入需要测试的对象

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService;
}

⑤创建测试方法进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService;
    @Test
    public void testUserService(){
   	 userService.save();
    }
}

Spring集成Junit步骤

①导入spring集成Junit的坐标

②使用@Runwith注解替换原来的运行期

③使用@ContextConfiguration指定配置文件或配置类

④使用@Autowired注入需要测试的对象

@RunWith(SpringJUnit4ClassRunner.class)
//加载spring核心配置文件
//@ContextConfiguration(value = {"classpath:applicationContext.xml"})
//加载spring核心配置类
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
}

④使用@Autowired注入需要测试的对象

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService;
}

⑤创建测试方法进行测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class SpringJunitTest {
    @Autowired
    private UserService userService;
    @Test
    public void testUserService(){
   	 userService.save();
    }
}

Spring集成Junit步骤

①导入spring集成Junit的坐标

②使用@Runwith注解替换原来的运行期

③使用@ContextConfiguration指定配置文件或配置类

④使用@Autowired注入需要测试的对象

⑤创建测试方法进行测试

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值