1.启动相关
@SpringBootApplication
包含了 @ComponentScan、@Configuration 和 @EnableAutoConfiguration 注解。
@ComponentScan
其中 @ComponentScan 让 spring Boot 扫描被@Component (@Service,@Controller)注解的 bean到 Configuration 类并把它加入到程序上下文。
@Configuration(下面有详细版本)
@Configuration 等同于 spring 的 XML 配置文件;允许在 Spring 上下文中注册额外的 bean 或导入其他配置类。
@EnableAutoConfiguration
@EnableAutoConfiguration 启用 SpringBoot 的自动配置机制。
2.Spring Bean 相关
@Autowired
自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。
@Slf4j
@Service
public class ProjectServiceImpl implements ProjectService {
}
@Autowired
private ProjectService projectService;
@PostMapping ("/application")
public ResultVo findProject(@RequestBody @Validated FindProjectRequest request) {
return projectService.findProject(request);
}
@Resource
public class Hello {
@Resource(name = "HappyClient")
private HappyClient happyClient;
@Resource(type = HappyPlayAno .class)
private HappyPlayAno happyPlayAno;
}
@Resource的作用相当于@Autowired,均可标注在字段或属性的setter方法上。
这个地方注意一下 这里的区别???????????????????
a:提供方 @Autowired是Spring的注解,@Resource是javax.annotation注解,而是来自于JSR-250,J2EE提供,需要JDK1.6及以上。
b :注入方式 @Autowired只按照Type 注入;@Resource默认按Name自动注入,也提供按照Type 注入;
c:属性
@Autowired注解可用于为类的属性、构造器、方法进行注值。默认情况下,其依赖的对象必须存在(bean可用),如果需要改变这种默认方式,可以设置其required属性为false。
还有一个比较重要的点就是,@Autowired注解默认按照类型装配,如果容器中包含多个同一类型的Bean,那么启动容器时会报找不到指定类型bean的异常,解决办法是结合**@Qualifier**注解进行限定,指定注入的bean名称。
@Resource有两个中重要的属性:name和type。name属性指定byName,如果没有指定name属性,当注解标注在字段上,即默认取字段的名称作为bean名称寻找依赖对象,当注解标注在属性的setter方法上,即默认取属性名作为bean名称寻找依赖对象。
需要注意的是,@Resource如果没有指定name属性,并且按照默认的名称仍然找不到依赖对象时, @Resource注解会回退到按类型装配。但一旦指定了name属性,就只能按名称装配了。
d:@Resource注解的使用性更为灵活,可指定名称,也可以指定类型 ;@Autowired注解进行装配容易抛出异常,特别是装配的bean类型有多个的时候,而解决的办法是需要在增加@Qualifier进行限定。
@RestController
@RestController 注解是 @Controller和 @ResponseBody 的合集, 表示这是个控制器 bean, 并且是将函数的返回值直接填入 HTTP 响应体中, 是 REST 风格的控制器。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
String value() default "";
}
@Repositor
标注一个DAO组件类。
@Service
标注一个业务逻辑组件类。
@Controller
@Controller:用于定义控制器类,在 spring 项目中由控制器负责将用户发来的 URL 请求转发到对应的服务接口(service 层)。一般这个注解在类中,通常方法需要配合注解 @RequestMapping使用。
@ResponseBody
@Controller
@RequestMapping("/test")
@Slf4j
public class TestController {
@RequestMapping("/hello.json")
@ResponseBody
public JsonData hello() {
log.info("hello");
return JsonData.success("hello, permission");
}
作用:将方法的返回值,以特定的格式写入到response的body区域,进而将数据返回给客户端。
当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。在使用此注解之后不会再走试图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
- 如果返回值是字符串,那么直接将字符串写到客户端;
- 如果是一个对象,会将对象转化为json串,然后写到客户端。
如果返回对象,按utf-8编码。如果返回String,默认按iso8859-1编码,页面可能出现乱码。因此在注解中我们可以手动修改编码格式,例如
@RequestMapping(value="/cat/query",produces="text/html;charset=utf-8"),
前面是请求的路径,后面是编码格式。
原理
控制层方法的返回值是如何转化为json格式的字符串的?其实是通过HttpMessageConverter中的方法实现的,它本是一个接口,在其实现类完成转换。
- 如果是bean对象,会调用对象的getXXX()方法获取属性值并且以键值对的形式进行封装,进而转化为json串。
- 如果是map集合,采用get(key)方式获取value值,然后进行封装。
@Component、@Repository、@Service、@Controller实质上属于同一类注解,用法相同,功能相同,区别在于标识组件的类型。
@Component可以代替@Repository、@Service、@Controller,因为这三个注解是被@Component标注的。 如下代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
String value() default "";
}
此处引用大神的文章https://blog.csdn.net/jiahao1186/article/details/91980316
@Scope
声明 Spring Bean 的作用域,使用方法:
@Bean
@Scope("singleton")
public Person personSingleton() {
return new Person();
}
四种常见的 Spring Bean 的作用域:
- singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
- prototype : 每次请求都会创建一个新的 bean 实例。
- request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
- session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
@Configuration
一般用来声明配置类,可以使用 @Component注解替代,不过使用Configuration注解声明配置类更加语义化。
使用@Configuration 用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@Configuration
public class AppConfig {
@Bean
public MyService myService() {
return new MyServiceImpl();
}
}
这和 Spring 的 XML 文件中的非常类似
<beans>
<bean id="myService" class="com.acme.services.MyServiceImpl"/>
</beans>
注意:@Configuration注解的配置类有如下要求:
- 1.@Configuration不可以是final类型;
- 2.@Configuration不可以是匿名类;
- 3.嵌套的configuration必须是静态类。
@Configuration的使用
可以看这篇大神的文章https://www.cnblogs.com/duanxz/p/7493276.html
@Component
@Configuration
public static class Config {
@Bean
public SimpleBean simpleBean() {
return new SimpleBean();
}
@Bean
public SimpleBeanConsumer simpleBeanConsumer() {
return new SimpleBeanConsumer(simpleBean());
}
}
@Component
public static class Config {
@Bean
public SimpleBean simpleBean() {
return new SimpleBean();
}
@Bean
public SimpleBeanConsumer simpleBeanConsumer() {
return new SimpleBeanConsumer(simpleBean());
}
}
- 第一个代码正常工作,正如预期的那样,SimpleBeanConsumer将会得到一个单例SimpleBean的链接。
- 第二个配置是完全错误的,因为Spring会创建一个SimpleBean的单例bean,但是SimpleBeanConsumer将获得另一个SimpleBean实例(也就是相当于直接调用new SimpleBean() ,这个bean是不归Spring管理的),既new SimpleBean() 实例是Spring上下文控件之外的。
原理解析
使用@ configuration,所有标记为@ bean的方法将被包装成一个CGLIB包装器,它的工作方式就好像是这个方法的第一个调用,那么原始方法的主体将被执行,最终的对象将在spring上下文中注册。所有进一步的调用只返回从上下文检索的bean。
在上面的第二个代码块中,新的SimpleBeanConsumer(simpleBean())只调用一个纯java方法。为了纠正第二个代码块,我们可以这样做
@Component
public static class Config {
@Autowired
SimpleBean simpleBean;
@Bean
public SimpleBean simpleBean() {
return new SimpleBean();
}
@Bean
public SimpleBeanConsumer simpleBeanConsumer() {
return new SimpleBeanConsumer(simpleBean);
}
}
大神链接:https://blog.csdn.net/u010648555/article/details/76299467
3.处理常见的 HTTP 请求类型
@RequestMapping
@RequestMapping:@RequestMapping(“/path”)表示该控制器处理所有 “/path” 的 UR L 请求。RequestMapping 是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。该注解有六个属性:
params
指定 request 中必须包含某些参数值是,才让该方法处理。
headers
指定 request 中必须包含某些指定的 header 值,才能让该方法处理请求。
@RequestMapping (value= "testHeaders" , headers={ "host=localhost" , "Accept" })
public String testHeaders() {
return "headers" ;
}
headers 属性的用法和功能与params 属性相似。在上面的代码中当请求/testHeaders.do 的时候只有当请求头包含Accept 信息,且请求的host 为localhost 的时候才能正确的访问到testHeaders 方法。
- value: 指定请求的实际地址,指定的地址可以是 URI Template 模式
@RequestMapping(value = "bkpic.page", method = RequestMethod.POST)
@ResponseBody
public JsonData upload(@RequestParam(value = "picture", required = false) MultipartFile picture, HttpServletRequest request) {
}
consumes
- 指定处理请求的提交内容类型(Content-Type),如 application/json,text/html;
produces
- 指定返回的内容类型,仅当 request 请求头中的 (Accept) 类型中包含该指定类型才返回
@RequestParam
@RequestMapping("/changeUsers.json")
@ResponseBody
public JsonData changeUsers(@RequestParam("roleId") int roleId, @RequestParam(value = "userIds", required = false, defaultValue = "") String userIds) {
List<Integer> userIdList = StringUtil.splitToListInt(userIds);
sysRoleUserService.changeRoleUsers(roleId, userIdList);
return JsonData.success();
}
@PathVariable: 路径变量。如
@RequestMapping(method = RequestMethod.GET)
public List<AccessDTO> searchAccess(@RequestParam(required = false) String service,
@RequestParam(required = false) String application,
@PathVariable String env) {
}
method
指定请求的 method 类型, GET、POST、PUT、DELETE 等
- GET :请求从服务器获取特定资源。举个例子:GET /users(获取所有学生)
@GetMapping("users") 等价于@RequestMapping(value="/users",method=RequestMethod.GET)
@GetMapping("/users")
public ResponseEntity<List<User>> getAllUsers() {
return userRepository.findAll();
}
- POST :在服务器上创建一个新的资源。举个例子:POST /users(创建学生)
@PostMapping("users") 等价于@RequestMapping(value="/users",method=RequestMethod.POST)
@PostMapping("/users")public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest userCreateRequest) {
return userRespository.save(user);
}
- PUT :更新服务器上的资源(客户端提供更新后的整个资源)。举个例子:PUT /users/12(更新编号为 12 的学生)
@PutMapping("/users/{userId}") 等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT)
@PutMapping("/users/{userId}")public ResponseEntity<User> updateUser(@PathVariable(value = "userId") Long userId,
@Valid @RequestBody UserUpdateRequest userUpdateRequest) {
......
}
- DELETE :从服务器删除特定的资源。举个例子:DELETE /users/12(删除编号为 12 的学生)
@DeleteMapping("/users/{userId}")等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE)
@DeleteMapping("/users/{userId}")public ResponseEntity deleteUser(@PathVariable(value = "userId") Long userId){
......
}
- PATCH :更新服务器上的资源(客户端提供更改的属性,可以看做作是部分更新),使用的比较少,这里就不举例子了。
一般实际项目中,我们都是 PUT 不够用了之后才用 PATCH 请求去更新数据。
@PatchMapping("/profile")
public ResponseEntity updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) {
studentRepository.updateDetail(studentUpdateRequest);
return ResponseEntity.ok().build();
}
4.读取配置信息
数据源application.yml
wuhan2020: 2020年武汉加油!中国加油!
my-profile:
name:哥
email:@163.com
library:
location: 湖北武汉加油中国加油
books:
- name: 1
description: 11
- name: 2
description: 22
- name: 3
description: 33
@value(常用)
使用 @Value("${property}") 读取比较简单的配置信息:
@Value("${wuhan2020}")
String wuhan2020;
@ConfigurationProperties
@Component
@ConfigurationProperties(prefix = "library")
class LibraryProperties {
@NotEmpty
private String location;
private List<Book> books;
@Setter
@Getter
@ToString
static class Book {
String name;
String description;
}
省略getter/setter
......
}
通过@ConfigurationProperties读取配置信息并与 bean 绑定。
@PropertySource
@PropertySource读取指定 properties 文件
@Component
@PropertySource("classpath:website.properties")
class WebSite {
@Value("${url}")
private String url;
省略getter/setter
......
}
这里借鉴了大神的文章https://segmentfault.com/a/1190000022521844
5.参数校验
JSR(Java Specification Requests) 是一套 JavaBean 参数校验的标准,它定义了很多常用的校验注解,我们可以直接将这些注解加在我们 JavaBean 的属性上面,这样就可以在需要校验的时候进行校验了,非常方便!
一些常用的字段验证的注解
@NotEmpty 被注释的字符串的不能为 null 也不能为空
@NotBlank 被注释的字符串非 null,并且必须包含一个非空白字符
@Null 被注释的元素必须为 null
@NotNull 被注释的元素必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Pattern(regex=,flag=)被注释的元素必须符合指定的正则表达式
@Email 被注释的元素必须是 Email 格式。
@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=)被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
......
示例
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
@NotNull(message = "classId 不能为空")
private String classId;
@Size(max = 33)
@NotNull(message = "name 不能为空")
private String name;
@Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围")
@NotNull(message = "sex 不能为空")
private String sex;
@Email(message = "email 格式不正确")
@NotNull(message = "email 不能为空")
private String email;
}
我们在需要验证的参数上加上了@Valid注解,如果验证失败,它将抛出
MethodArgumentNotValidException。
@RestController
@RequestMapping("/api")
public class PersonController {
@PostMapping("/person")
public ResponseEntity<Person> getPerson(@RequestBody @Valid Person person) {
return ResponseEntity.ok().body(person);
}
}
一定一定不要忘记在类上加上 Validated 注解了,这个参数可以告诉 Spring 去校验方法参数。
@RestController
@RequestMapping("/api")
@Validated
public class PersonController {
@GetMapping("/person/{id}")
public ResponseEntity<Integer> getPersonByID(@Valid @PathVariable("id") @Max(value = 5,message = "超过 id 的范围了") Integer id) {
return ResponseEntity.ok().body(id);
}
}
6.@Transactional
在要开启事务的方法上使用@Transactional注解即可!
@Transactional(rollbackFor = Exception.class)
public void save() {
......
}
我们知道 Exception 分为运行时异常 RuntimeException 和非运行时异常。
在@Transactional注解中如果不配置rollbackFor属性,那么事务只会在遇到RuntimeException的时候才会回滚,加上rollbackFor=Exception.class,可以让事务在遇到非运行时异常时也回滚。
@Transactional 注解一般用在可以作用在类或者方法上。
- 作用于类:当把@Transactional 注解放在类上时,表示所有该类的public 方法都配置相同的事务属性信息。
- 作用于方法:当类配置了@Transactional,方法也配置了@Transactional,方法的事务会覆盖类的事务配置信息。
示例
@Service
public class CompanyServiceImpl implements CompanyService {
@Autowired
private CompanyDAO companyDAO;
@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = Exception.class)
public int deleteByName(String name) {
int result = companyDAO.deleteByName(name);
return result;
}
...
}
未完待续。。。。。。。 欢迎留言。。。
@Inherited
https://blog.csdn.net/ab411919134/article/details/81252516
@ConditionalOnClass
https://blog.csdn.net/lbh199466/article/details/88303897
@Target
https://blog.csdn.net/qq_30347133/article/details/83686068?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=1331979.23999.16187142306795993&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
@Retention
https://blog.csdn.net/b_just/article/details/106528250
@SuppressWarnings
https://blog.csdn.net/u012994320/article/details/83083392
@Aspect
https://blog.csdn.net/zhengchao1991/article/details/53391244?utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7EBlogCommendFromMachineLearnPai2%7Edefault-1.control
https://blog.csdn.net/fz13768884254/article/details/83538709
@Slf4j
@EnableWebMvc
@Primary
@EnableSwagger2
@EnableAsync
@Authority(needLogin = true)
@ResponseStatus(HttpStatus.CREATED)
@PmsKey(code = “application”, title = “应用列表”)
@SerializedName(“biz_id”)
@ControllerAdvice(annotations = ResponseBody.class)
@ExceptionHandler(value = Exception.class)
@Order(0)
@Around(“execution(* org.apache.dubbo.admin.controller..(…))”)
@SPI(“zookeeper”)
@EnableTransactionManagement
@MapperScan(basePackages = “org.apache.dubbo.admin.dao.mapper”)
@ComponentScan(basePackageClasses = {org.apache.dubbo.admin.DubboAdminApplication.class, PermitContextManager.class})
本公众号分享自己从程序员小白到经历春招秋招斩获10几个offer的面试笔试经验,其中包括【Java】、【操作系统】、【计算机网络】、【设计模式】、【数据结构与算法】、【大厂面经】、【数据库】期待你加入!!!
1.计算机网络----三次握手四次挥手
2.梦想成真-----项目自我介绍
3.你们要的设计模式来了
4.一字一句教你面试“个人简介”
5.接近30场面试分享
转载:https://blog.csdn.net/weixin_41563161/article/details/116072910