容器分析
手动注册WebApplicationContext
public class ServletConfig extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createServletApplicationContext() {
//获取SpringMVC容器
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(SpringMvcConfig.class);
return context;
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
tomcat 服务器启动的时候,加载ServletConfig类之后,做初始化web容器操作,相当于 web.xml
执行注册容器的方法,获取 SpringMVC容器 WebApplicationContext
@Nullable
protected WebApplicationContext createRootApplicationContext() {
Class<?>[] configClasses = this.getRootConfigClasses();
if (!ObjectUtils.isEmpty(configClasses)) {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(configClasses);
return context;
} else {
return null;
}
}
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
Class<?>[] configClasses = this.getServletConfigClasses();
if (!ObjectUtils.isEmpty(configClasses)) {
context.register(configClasses);
}
return context;
}
通过@ComponentScan(“cn.sycoder.controller”) 加载 Controller 下面的bean 进 WebApplicationContext
@RestController
public class TestController {
@GetMapping("/test/{id}")
public String test(@PathVariable Long id) {
return "ok:" + id;
}
}
把使用了 RequestMapping 注解的方法的 value — 对应一个方法,建立起了一对一映射关系(可以想象hashmap)
将spring配置注入到 web 容器中
@Configuration
@ComponentScan(value={"cn.sycoder.service","cn.sycoder.dao"})
public class SpringConfig {
}
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
验证代码
@Test
public void test(){
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(SpringConfig.class);
ITestService bean = applicationContext.getBean(ITestService.class);
bean.get(1L);
TestController bean1 = applicationContext.getBean(TestController.class);
System.out.println(bean1.test(1L));
}
导入依赖
配置 web 项目入口配置替换 web.xml(AbstractAnnotationConfigDispatcherServletInitializer)
配置 Spring 配置类交给 web 容器管理
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
配置 SpringMVC 配置类交给 web 容器管理
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
配置请求拦截规则,交给 springmvc 处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
依赖
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.17.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.17.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.17.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
SpringConfig(在整合项目的时候不能扫描mvc的类,否则会出现创建容器失败)
@Configuration
@ComponentScan(value = {"cn.sycoder.service","cn.sycoder.dao"})
@EnableTransactionManagement
@PropertySource("classpath:db.properties")
@Import({DbConfig.class,MybatisConfig.class})
public class SpringConfig {
}
创建数据库配置文件
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.username=root
jdbc.password=123456
创建DbConfig
public class DbConfig {
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
/**
* 配置德鲁伊连接池
* @return
*/
@Bean
public DataSource dataSource(){
DruidDataSource source = new DruidDataSource();
source.setUrl(url);
source.setDriverClassName(driver);
source.setPassword(password);
source.setUsername(username);
return source;
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource){
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSource);
return manager;
}
}
MyBatisConfig
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setTypeAliasesPackage("cn.sycoder.domain");
return bean;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("cn.sycoder.dao");
return configurer;
}
}
SpringMvcConfig
@Configuration
@ComponentScan("cn.sycoder.controller")
@EnableWebMvc
public class SpringMvcConfig {
}
ServletConfig
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};//配置Spring交给Web 管理
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
创建 ssm 数据库
创建 item 表
create table item
(
id bigint auto_increment,
type varchar(64) null,
name varchar(64) null,
remark text null,
constraint item_pk
primary key (id)
);
添加 lombok 依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
模型类
@Data
public class Item {
private Long id;
private String name;
private String type;
private String remark;
}
Mapper 接口
@Repository
public interface ItemMapper {
@Insert("insert into item(name,type,remark) value(#{name},#{type},#{remark})")
public int save(Item item);
@Delete("delete from item where id = #{id}")
public int delete(Long id);
@Update("update item set name = #{name},type = #{type},remark=#{remark} where id=#{id}")
public int update(Item item);
@Select("select * from item where id = #{id}")
public Item getById(Long id);
@Select("select * from item")
public List<Item> list();
}
Service 接口
public interface IItemService {
/**
* 添加闲置物品方法
* @param item
* @return
*/
public boolean save(Item item);
/**
* 删除闲置物品
* @param id
* @return
*/
public boolean delete(Long id);
/**
* 更新闲置物品
* @param item
* @return
*/
public boolean update(Item item);
/**
* 查询闲置物品通过id
* @param id
* @return
*/
public Item getById(Long id);
/**
* 查询所有闲置商品
* @return
*/
public List<Item> lists();
}
定义接口实现类
@Service
public class ItemServiceImpl implements IItemService {
@Autowired
ItemMapper mapper;
@Override
@Transactional
public boolean save(Item item) {
return mapper.save(item) > 0;
}
@Override
@Transactional
public boolean delete(Long id) {
return mapper.delete(id) >0;
}
@Override
@Transactional
public boolean update(Item item) {
return mapper.update(item) >0;
}
@Override
public Item getById(Long id) {
return mapper.getById(id);
}
@Override
public List<Item> lists() {
return mapper.list();
}
}
Controller
@RestController
@RequestMapping("/item")
public class ItemController {
@Autowired
IItemService service;
@PostMapping
public boolean save(@RequestBody Item item){
return service.save(item);
}
@PutMapping
public boolean update(@RequestBody Item item){
return service.update(item);
}
@DeleteMapping("/{id}")
public boolean delete(@PathVariable Long id){
return service.delete(id);
}
@GetMapping("/{id}")
public Item getById(@PathVariable Long id){
return service.getById(id);
}
@GetMapping
public List<Item> list(){
return service.lists();
}
}
修改Spring配置类
@Configuration
@ComponentScan(value = {"cn.sycoder.service","cn.sycoder.dao"})
@EnableTransactionManagement
@PropertySource("classpath:db.properties")
@Import({DbConfig.class,MybatisConfig.class})
public class SpringConfig {
}
准备 item 数据
{"name":"键盘","type":"电脑外设","remark":"9成新,半价卖"}
{"name":"笔记本","type":"电脑","remark":"9成新,8折出售"}
{"name":"鞋子","type":"收藏鞋","remark":"科比签名的,独一无二"}
添加数据
目录结构
新建测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class ItemTest {
@Autowired
IItemService service;
@Test
public void save(){
Item item = new Item();
item.setName("单元测试");
item.setRemark("单元测试");
item.setType("单元测试");
boolean save = service.save(item);
System.out.println(save);
}
@Test
public void update(){
Item item = new Item();
item.setId(5L);
item.setName("单元测试");
item.setRemark("单元测试");
item.setType("单元测试");
boolean save = service.update(item);
System.out.println(save);
}
@Test
public void getById(){
Item byId = service.getById(5L);
System.out.println(byId);
}
@Test
public void list(){
List<Item> lists = service.lists();
System.out.println(lists);
}
}
设置访问 index 访问主页
@Controller
public class IndexController {
@RequestMapping("/index")
public String index(){
System.out.println("----------------");
return "/pages/items.html";
}
}
出现静态资源被拦截问题
@Configuration
public class StaticSupport extends WebMvcConfigurationSupport {
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
}
}
将 staticSupport 交给 SpringMvc 管理
@Configuration
@ComponentScan(value = {"cn.sycoder.controller","cn.sycoder.config"})
@EnableWebMvc
public class SpringMvcConfig {
}
保存方法
handleAdd () {
console.log("========")
axios.post("/item",this.formData).then((res)=>{
//todo
})
},
列表查询
getAll() {
axios.get("/item",).then((res)=>{
this.dataList = res.data;
})
},
删除操作
handleDelete(row) {
axios.delete("/item/"+row.id).then((res)=>{
//todo
})
}