参考:spring-boot
有Java基础,初学使用spring-boot;内部原理还不懂,在使用层面给出自己的理解。
实践环境:
- Java -version:1.8
- maven 3.6
- Idea
初始化项目
spring initializr初始化一个spring-boot项目,下载。在本地IDEA中导入。
最佳实践项目目录,
-
DemoApplication.java
主程序入口,
在同级目录按代码职能(或业务功能)建立包(package),代码编写。@SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }
注解
@SpringBootApplication
包含了一下职能的注解:
1.@Configuration
为一些需要配置属性的类定义了上下文环境
2.@EnableAutoConfiguration
告诉spring-boot 添加基于类路径下的一些配置。
3.@EnableWebMvc
定义项目作为web应用功能程序运行,可以处理一些分发请求。
4.@ComponentScan
告诉spring-boot 程序扫描com.example.demo
包路径下的文件,组件、配置、服务、控制器。 -
DemoApplicationTests.java
测试类测试控制器接口请求、服务类的方法等。
@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest @AutoConfigureMockMvc public class DemoApplicationTests { @Autowired private MockMvc mvc; @Test public void getHello() throws Exception{ mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("hello world"))); } }
@SpringBootTest
注解创建了整个项目的上下文环境。我们在测试配置属性时需要上下文环境去访问配置文件。
@AutoConfigureMockMvc
创建实例时注入MockMvc
实例,调用方法模拟http请求,对请求结果进行断言。 -
application.properties
配置文件,用于一些自定义属性、模块的配置属性定义…
控制器
处理http请求、业务逻辑处理。
package com.example.demo.test;
@RestController
public class HelloContorller {
@RequestMapping("/hello")
public String index(){
return "hello world";
}
}
-
@RestController
结合了一下注解的职能:
@Controller
定义控制器类,处理http请求
@ResponseBody
返回请求数据写入 http response body中。在构建RestFul的API时,直接返回JSON格式数据。 -
@RequestMapping
映射的http请求路由地址。可注解类、方法。
运行
-
右键
DemoApplication .java
运行,日志打印没有出现错误启动成功。
浏览器访问localhost:8080/hello
-
测试运行
右键测试类DemoApplicationTests.java
运行:
等待执行没报错说明测试成功,可以将期待值修改在测试看结果:mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo("hello world and you")));
测试不通过,很方便测试接口。右键测试类会运行整个测试类中的方法,执行测试一个方法时,鼠标 聚焦该方法上,右键运行该方法。
项目配置文件pox.xml
添加项目需要的依赖、插件等。
// 核心依赖,默认会加载项目中用到的jar包,当出现使用冲突时需要手动设定不加载。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
// 测试类依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
// web应用程序依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
// 管理应用程序的服务,监控程序运行、运行环境情况
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
遇到的问题
-
有许多应用程序jar中包含相同名字的类名,自动加载时注意。不然那报错都不知道为什么。
对这些jar包功能不熟悉导致,它承担的职责不清楚导致。 -
Java环境、最好使用 jdk 1.8 ,而且Java -version 1.8 + ,
新稳定版,技术更新很快,偶然的一个新特性在使用报错中很头疼。pom.xml
要配置的:
file menu -> project structure -> poject
jdk 环境,使用语言的级别。
业务模块
业务模块操作流程。
数据操作
-
spring-data-jpa
pom.xml
spring-data-jpa
提供了简介的数据库操作方法, 默认实现基本的增、删、改、查。还提供一些常用的操作语句查看博客详解spring-data-jpa,写的很好 ,需要一些复杂的语句则使用注解@Query
自定义sql语句,如果是删除、更新操作需要使用注解@Modifying
;添加注解@Transactional
对事物的支持(还未了解)<!-- 数据处理操作 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- 嵌入内存的关系型数据库 --> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency>
定义实体类,
@Entity public class Customer { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; private String name; private int age; protected Customer() { } public Customer(String name,int age){ this.name = name; this.age = age; } @Override public String toString() { return String.format("User[id=%d,name='%s',age=%d]",id,name,age); } // 省略了getter、setter方法 }
定义
CustomerRepository
接口继承CrudRepository
使用默认方法或自定义操作方法。默认方法:
save()
/delete()
/findAll
等等。public interface CustomerRepository extends CrudRepository<Customer,Long> { List<Customer> findByName(String name); }
测试:
执行getUserData()
方法,@Before
注解的方法会在执行测试方法之前先执行,进行数据初始化插入。@RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest @AutoConfigureMockMvc public class DemoApplicationTests { private static final Logger log = LoggerFactory.getLogger(DemoApplication.class); @Autowired private CustomerRepository repository; @Before public void index() throws Exception{ repository.save(new Customer("jack",32)); repository.save(new Customer("Frey",32)); repository.save(new Customer("Harro",32)); repository.save(new Customer("Kenfi",32)); } @Test public void getUserData() throws Exception{ log.info("Customers found width findAll()"); log.info("-------------------------------"); for(Customer customer:repository.findAll()){ log.info(customer.toString()); } log.info("query all and shows"); repository.findById(2L) .ifPresent(customer -> { log.info("Customer found with findById(2L)"); log.info("--------------------------------"); log.info(customer.toString()); log.info("just one data"); }); log.info("Customer found width findByName('jack')"); log.info("---------------------------------------"); repository.findByName("jack").forEach(item->{ log.info(item.toString()); }); log.info("ending"); } }