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= ...
随机推荐
- 64位系统下,一个32位的程序究竟可以申请到多少内存,4GB还是更多?(一)
前言: cpu的位是指一次性可处理的数据量是多少,1字节=8位,32位处理器可以一次性处理4个字节的数据量,依次类推.32位操作系统针对的32位的CPU设计.64位操作系统针对的64位的CPU设计.操 ...
- Openstack(Kilo)安装系列之neutron(九)
控制节点 Before you configure the OpenStack Networking (neutron) service, you must create a database, se ...
- oracledbconsole db启动问题
oracledbconsole db启动问题 被这个OracleDBconsole服务无法启动的问题折磨了两个星期了,今天很幸运,在网上无意间看到了一位大侠的思路,虽然错误的情况并不完全相同,但他的思 ...
- VUE:使用vue-cli脚手架无法安装npm install axios 的巨坑
使用命令 npm install axios 安装axios可能会报错,无法引用, 这个时候使用淘宝的镜像cnpm安装就可以了 cnpm install axios 如果没有安装cnpm,执行以下命令 ...
- 面试题思考:java中快速失败(fail-fast)和安全失败(fail-safe)的区别是什么?
一:快速失败(fail—fast) 在用迭代器遍历一个集合对象时,如果遍历过程中对集合对象的内容进行了修改(增加.删除.修改),则会抛出Concurrent Modification Exceptio ...
- 60、常规控件(3)Snackbar-可操作的提示框,Toast升级版
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app=&quo ...
- Array转为Json需要导入的包
今天自己写了一个JSON的例子,可以一调用就出了问题,报下面这个异常: java.lang.ClassNotFoundException: org.apache.commons.lang.except ...
- Webservice工作原理及实例
Web Service工作原理及实例 一.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者In ...
- 转义字符的理解(JAVA、字符串和正则表达式)
一.原理总结: 要理解转义,首先要从正则表达式说起. 在正则表达式中:*和\是特殊字符:为了匹配这两个字符本身,正则表达式中需要写为\*和\\ 在Java中,只能用字符串表示正则表达式,所以需要把\* ...
- ZOJ 3941 Kpop Music Party(省赛, 贪心)
Kpop Music Party Time Limit: 2 Seconds Memory Limit: 65536 KB Marjar University often hosts Kpo ...