Spring 之 @ComponentScan以及mock Spring MVC
【 @ComponentScan】
纠正:可以成功 Autowired 的原因是我在另外一个 config 文件中扫描了根包,这会顺带扫描所有该包的子包
还有,,上面的写法容易出错,建议这样写,
@ComponentScan(basePackageClasses={Spittle.class},
效果上是完全等价的,只不过不再需要自己写字符串了, Spittle 是根包下的类。
----------------------------------------------------------------------------------------------------------------------------------------
原文(错):发现一件奇怪的事情,我明明没有指定扫描那个包,却能 Autowired 那个包中的类的对象不出现异常。
按理来说,要自动装配某一个类的对象,首先,需要在那个类上标注 @Component 或者是 @Controller ;其次,需要扫描那个类所在的那个包。我的情况是条件二并不满足却获得了那个对象。我尝试给那个类去掉 @Component 注释,结果报错了,所以并不是条件一有问题,明显是由于 Spring 自主扫描了我没有显式指定的那个包,并为那个带有组件声明的类创建了对象。
更加显式地指定要扫描的那个包:
@ComponentScan(basePackageClasses={HomeController.class})
结果仍然是不报错地获得了我没有显式指定扫描的那个包的类的对象,实验之后发现,成功自动装配的条件应该是:
- 在类的上面有相应的组件声明,例如 @Component 或者是 @Controller ,或者其它等价注释。
- 类所在的包被直接显式指定扫描,或者该类被直接显示指定扫描的那个(些)包中的类所 import
总之不管怎样,作为组件的声明都是必须的。
【 mock Spring MVC 】
基于使用概率导入大量的依赖包有个缺点就是一旦依赖包出现问题很难锁定问题到底出在哪里!!!
这些问题通常是由于依赖包的版本造成的 ( ╯□╰ ) , 因此对于依赖包的导入务必保证不必要不导入,并添加一些适当的注释。
最好是能够清楚地了解各个包的用途、来源,这样也方便查相应的文档:
【pom.xml 模板】
标记为红色的是进行 mock 测试可能用到的包
<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>spittr</groupId>
<artifactId>spittr</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
</configuration>
</plugin>
</plugins>
</build> <dependencies>
<!-- spring-web 包括 web 、 bean 、aop 、 context 、 core 等 spring-webmvc 的子集-->
<!-- <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>3.2.9.RELEASE</version>
</dependency> --> <!-- jSTL taglibs-->
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
</dependency> <!-- spring-web 包括 web 、 bean 、aop 、 context 、 core、 webmvc 等 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.7.RELEASE</version>
</dependency> <!-- spring-test 包括 test 等,含 mock -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
<scope>test</scope>
</dependency> <!-- mock 相关的类库 -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency> <!-- hamcrest 相关的类库 -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency> <!-- junit 包括 junit 、 hamcrest -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- commons-lang 仅一个包,包括各种各样的工具,简化 hashCode 、 Equal 代码 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.4</version>
</dependency> </dependencies>
</project>
【 mock Mvc】
package spittr.web; import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
// 附上 API 文档地址: http://docs.spring.io/spring/docs/current/javadoc-api/
public class HomeControllerTest {
@Test
public void testHomePage() throws Exception {
HomeController controller = new HomeController();
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
mockMvc.perform(MockMvcRequestBuilders.get("/")).andExpect(MockMvcResultMatchers.view().name("home"));
}
}
可以修改为静态导入:
package spittr.web; import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
// 附上 API 文档地址: http://docs.spring.io/spring/docs/current/javadoc-api/
public class HomeControllerTest {
@Test
public void testHomePage() throws Exception {
HomeController controller = new HomeController();
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
mockMvc.perform(get("/")).andExpect(view().name("home"));
}
}
【 mock 一个接口的实现类】
package spittr.web; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.standaloneSetup; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.servlet.view.InternalResourceView; import spittr.Spittle;
import spittr.data.SpittleRepository; public class SpittleControllerTest {
@Test
public void shouldShowRecentSpittles() throws Exception {
List<Spittle> expectedSpittles = createSpittleList(20);
SpittleRepository mockRepository = mock(SpittleRepository.class);
when(mockRepository.findSpittles(Long.MAX_VALUE, 20)).thenReturn(expectedSpittles);
SpittleController controller = new SpittleController(mockRepository);
MockMvc mockMvc = standaloneSetup(controller).setSingleView(new InternalResourceView("/WEB-INF/views/spittles.jsp")).build();
mockMvc.perform(get("/spittles")).andExpect(view().name("spittles")).andExpect(model().attributeExists("spittleList"));
} public List<Spittle> createSpittleList(int count) {
List<Spittle> spittles = new ArrayList<>();
for (int i = 0; i < count; ++i) {
spittles.add(new Spittle("Spittle" + i, new Date()));
}
return spittles;
}
}
Spring 之 @ComponentScan以及mock Spring MVC的更多相关文章
- Spring Data MongoDB example with Spring MVC 3.2
Spring Data MongoDB example with Spring MVC 3.2 Here is another example web application built with S ...
- [转]Spring Boot——2分钟构建spring web mvc REST风格HelloWorld
Spring Boot——2分钟构建spring web mvc REST风格HelloWorld http://projects.spring.io/spring-boot/ http://spri ...
- 结合源码浅谈Spring容器与其子容器Spring MVC 冲突问题
容器是整个Spring 框架的核心思想,用来管理Bean的整个生命周期. 一个项目中引入Spring和SpringMVC这两个框架,Spring是父容器,SpringMVC是其子容器,子容器可以看见父 ...
- Spring:基于注解的Spring MVC
什么是Spring MVC Spring MVC框架是一个MVC框架,通过实现Model-View-Controller模式来很好地将数据.业务与展现进行分离.从这样一个角度来说,Spring MVC ...
- Spring使用ComponentScan扫描Maven多模块工程的其它模块
说明:在新建好了Maven多模块工程后,如果想要在其它模块也能使用Spring的对象管理,比如@Autowrited这些注入方式,那么就必须开启包扫描的功能才能使其进行注入到Spring的对象管理中. ...
- Spring入门(十四):Spring MVC控制器的2种测试方法
作为一名研发人员,不管你愿不愿意对自己的代码进行测试,都得承认测试对于研发质量保证的重要性,这也就是为什么每个公司的技术部都需要质量控制部的原因,因为越早的发现代码的bug,成本越低,比如说,Dev环 ...
- spring <context:component-scan>使用说明(转)
在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类 ...
- spring <context:component-scan>(转)
在xml配置了这个标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类 ...
- Spring context:component-scan中使用context:include-filter和context:exclude-filter
Spring context:component-scan中使用context:include-filter和context:exclude-filter XML: <?xml version= ...
随机推荐
- 《Node.js入门》CentOS 6.5下Node.js Web开发环境搭建笔记
近期想尝试一下英特尔的基于WebRTC协同通信开发套件,所以须要在本地搭建Node.js Web的开发測试环境. 这里讲的是CentOS 下的搭建方法.使用Windows的小伙伴请參考: <No ...
- MVC结构简介
本文编译自J2EE的相关文档.MVC(Model-View-Controller)应用程序结构被用来分析分布式应用程序的特征.这种抽象结构能有助于将应用程序分割成若干逻辑部件,使程序设计变得更加容易. ...
- LNMP+Zabbix搭建
LNMP+Zabbix搭建 cmake2.8.8,Nginx-1.6.3,Php-5.5.38,Mysql-5.5.32,Zabbix-3.2.6 修改 /etc/selinux/config 文件中 ...
- github删除已经push到服务器上的commit的方法
使用两条指令: git reset --hard <commit_id> git push origin HEAD --force 其中commit_id是你想回到的commit的id(即 ...
- 【BZOJ4631】踩气球 链表+线段树+堆
[BZOJ4631]踩气球 Description 六一儿童节到了, SHUXK 被迫陪着M个熊孩子玩一个无聊的游戏:有N个盒子从左到右排成一排,第i个盒子里装着Ai个气球. SHUXK 要进行Q次操 ...
- 160701、理解 Promise 的工作原理
Javascript 采用回调函数(callback)来处理异步编程.从同步编程到异步回调编程有一个适应的过程,但是如果出现多层回调嵌套,也就是我们常说的厄运的回调金字塔(Pyramid of Doo ...
- pip安装Scrapy框架报错
安装: pip3 install scrapy==1.1.0rc3 一..解决scrapy安装错误: 二.具体操作: 1.在http://landinghub.visualstudio.com/vis ...
- Oracle中sql相关的命令
1.创建用户 SQL> -- 例如创建一个用户名为xiaoming,密码为a123的用户 SQL> create user xiaomingidentified by a123; 用户已创 ...
- 四、H5 录制视频 Web Real-Time Communication
Web Real-Time Communication HTML5实现视频直播功能思路详解_html5教程技巧_脚本之家 https://m.jb51.net/html5/587215.html
- 直播未来属于RTMP还是HTTP
直播未来属于RTMP还是HTTP? - Tinywan - 博客园 https://www.cnblogs.com/tinywan/p/6122065.html 直播未来属于RTMP还是HTTP? H ...