前言

本篇随笔将对 Spring Boot 中的常用注解做一个简单的整理归档,写作顺序将从启动类开始并逐步向内外扩展,目的即为了分享也为了方便自己日后的回顾与查阅。

1. Application

启动类示例如下:

@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

第一个要讲解的注解是:@SpringBootApplication,从直观的感受来看,他是 SpringApplication 能够进入一系列复杂启动流程的先决条件。进入源码我们可以观察到这是一个组合注解,其切面之上还有三个注解,分别为:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。

@SpringBootConfiguration 中真正起作用的是 @Configuration,即标注当前类为 JavaConfig 配置类(这里扩展一下,任何标注了 @Configuration 的类都为配置类,任何标注了 @Bean 的方法其返回值都是一个 Bean 的定义)。

@EnableAutoConfiguration 是构成上诉组合注解的核心,从名称上就能获取到浅显的信息:启用自动配置,他借助 @Import 将所有符合条件的 @Configuration 配置都注入到 IoC 容器中,定义如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}

@ComponentScan 顾名思义,他会扫描带有特定标注的组件(如 @Controller、@Component、@Service、@Repository),并将其注入到 IoC 容器中。

2. Test

测试类示例如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
@Test
public void contextLoads() {
}
}

@RunWith(SpringRunner.class) 翻译一下就是使用 Spring 的 IoC 容器运行测试;@SpringBootTest 创建了 SpringApplication 的上下文;@Test 标注测试方法。在此推荐阅读 “SpringBoot单元测试” ,写得很详细,我就不再赘述了,待有空补几篇复杂测试的案例分析。

3. 基本注解

3.1 @Service & @Repository

他们是在 Spring Boot 中轻松实现面向接口编程的关键,一个用于逻辑层,一个用于数据层,示例如下:

public interface HelloService {
String notSay();
}
@Service
public class HelloServiceImpl implements HelloService {
@Override
public String notSay() {
return "shut up";
}
}

个人认为此处非常形象地体现了 “约定优于配置”,可以理解为 Spring Boot 默认配置了这么一条 Bean:

<bean id="HelloService" class="com.youclk.annotation.service.impl.HelloServiceImpl"></bean>

3.2 @Component

标注组件,可以作用在任何层次。

3.3 @Controller

控制器示例如下:

@RestController
public class HelloController { private final HelloService helloService; @Autowired
public HelloController(HelloService helloService) {
this.helloService = helloService;
} @GetMapping("/{id}")
public String say(@PathVariable("id") Integer id, @RequestParam("name") String name) {
return (String.format("id=%d,name=%s;please %s", id, name, helloService.notSay()));
}
}

@RestController 查看源码可观察出其为 @Controller + @ResponseBody 的组合注解:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
@AliasFor(annotation = Controller.class)
String value() default "";
}

@GetMapping 其实就是对 @RequestMapping(method = RequestMethod.GET) 的进一步封装,同理的还有 Post、Delete、Put 等等,不同类型的请求都有其对应封装,能少打不少代码。

其他的在示例中也一目了然了:@Autowired 自动转配;@PathVariable 从 Url 中取值;@RequestParam 从参数中取值。

4. 异常处理

示例如下:

@ControllerAdvice
public class GlobalException {
@ResponseBody
@ExceptionHandler
public String processException(Exception e) {
return "error: " + e.getMessage();
}
}

没啥好说的,@ExceptionHandler 可以过滤具体的异常类型:@ExceptionHandler(Exception.class)

5. 配置

通过 @Value 可以直接拿到配置文件中的属性,不过意义不是很大,例:

@Value("${my.name}")
private String name;

更多的时候应该去拿到一个对象,例:

@Component
@ConfigurationProperties(prefix = "my")
public class My {
private String name; private Integer age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
}
}

@Profiles 按环境变量激活,我觉得很不是很好的解决方案,没怎么用过,示例:

@profile("dev")
@profile("prod")

Spring Boot 提倡约定优于配置,但有的时候我们不想守约,如下:

@Configuration
public class DbConfiguration { private final Db db; @Autowired
public DbConfiguration(Db db) {
this.db = db;
} @Bean(name = "dataSource")
public DataSource dataSource() {
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName(db.driverClassName);
dataSource.setUrl(db.driverUrl);
dataSource.setUsername(db.driverUsername);
dataSource.setPassword(db.driverPassword);
return dataSource;
} @Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
} }

6. 其他

@Qualifier 是为了解决一个接口对应多个实现的冲突,不过在设计上一般都会避免这种情况,所以不是很常用,示例:

@Service("service1")
public class HelloServiceImpl1 implements HelloService {
} @Service("service2")
public class HelloServiceImpl2 implements HelloService {
}
@Autowired
@Qualifier("service1")
HelloService helloService;

@Resource(name="name",type="type") 和 @Autowired 类似,不常用。

结语

近期正在寻觅新的工作机会,若有意向,欢迎留言,微信: youclk。


我的公众号《有刻》,我们共同成长!

Java 小记 — Spring Boot 注解的更多相关文章

  1. Java 小记 — Spring Boot 的实践与思考

    前言 本篇随笔用于记录我在学习 Java 和构建 Spring Boot 项目过程中的一些思考,包含架构.组件和部署方式等.下文仅为概要,待闲时逐一整理为详细文档. 1. 组件 开源社区如火如荼,若在 ...

  2. Spring boot 注解简单备忘

    Spring boot 注解简单备忘 1.定义注解 package com.space.aspect.anno;import java.lang.annotation.*; /** * 定义系统日志注 ...

  3. Spring Boot 注解之ObjectProvider源码追踪

    最近依旧在学习阅读Spring Boot的源代码,在此过程中涉及到很多在日常项目中比较少见的功能特性,对此深入研究一下,也挺有意思,这也是阅读源码的魅力之一.这里写成文章,分享给大家. 自动配置中的O ...

  4. Spring Boot注解大全,一键收藏了!

    本文首发于微信公众号[猿灯塔],转载引用请说明出处 今天是猿灯塔“365天原创计划”第5天. 今天呢!灯塔君跟大家讲: Spring Boot注解大全 一.注解(annotations)列表 @Spr ...

  5. Spring boot注解(annotation)含义详解

    Spring boot注解(annotation)含义详解 @Service用于标注业务层组件@Controller用于标注控制层组件(如struts中的action)@Repository用于标注数 ...

  6. 73. Spring Boot注解(annotation)列表【从零开始学Spring Boot】

    [从零开始学习Spirng Boot-常见异常汇总] 针对于Spring Boot提供的注解,如果没有好好研究一下的话,那么想应用自如Spring Boot的话,还是有点困难的,所以我们这小节,说说S ...

  7. 框架-Java:Spring Boot

    ylbtech-框架-Java:Spring Boot 1.返回顶部 1. Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该 ...

  8. spring boot注解之@Scheduled定时任务实现

    java实现定时任务一般使用timer,或者使用quartz组件.现在在spring boot提供了更加方便的实现方式. spring boot已经集成了定时任务.使用@Secheduled注解. @ ...

  9. Spring Boot 注解详解

    一.注解(annotations)列表 @SpringBootApplication:包含了@ComponentScan.@Configuration和@EnableAutoConfiguration ...

随机推荐

  1. Codeforces 257D

    题意略. 思路:这个题目最重要的是那个不等式 a[i] <= a[i+1] <= 2 * a[i]  ,你会发现0 <= a[i+1]  -  a[i] <= a[i],令x ...

  2. linux中的三个文件时间

    Linux系统文件有三个主要的时间属性,分别是ctime(change time), atime(access time), mtime(modify time). 后来为了解决atime的性能问题, ...

  3. 网络基础Cisco路由交换二

    三层交换技术 作用: 使用三层交换技术实现VLAN间通信. 三层交换=二层交换+三层转发 基于CEF的快速转发 主要包含两个转发用的信息表: 转发信息库(FIB):FIB类似于路由表,包含路由表中转发 ...

  4. 个性化WinPE封装方法 ----最后实战“制作WinPE3.0图文教程”

    经过前几讲,主要目的就是准备一些"原材料",熟悉一些"命令",实际上是"战前演练准备".下面要进入"实战状态",成败在此 ...

  5. 错误代码: 1242 Subquery returns more than 1 row

    1. 错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:SELECT t.id, DATE_FORMAT( t.statisTim ...

  6. Linux显示计算次数的结果

    Linux显示计算次数的结果 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ free -c free:选项需要一个参数 -- c Usage: free [o ...

  7. oracle分析函数技术详解(配上开窗函数over())

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  8. 简单bfs(hdu2612)

    #include<stdio.h>#include<string.h>#include<queue>#define INF 0x3f3f3f3fusing name ...

  9. java io 节点流和处理流

    JAVA IO操作总结:节点流和处理流 JAVA IO操作总结--节点流和处理流  按照流是否直接与特定的地方(如磁盘.内存.设备等)相连,分为节点流和处理流两类. 节点流:可以从或向一个特定的地方( ...

  10. [POJ2115]C Looooops 拓展欧几里得

    原题入口 这个题要找到本身的模型就行了 a+c*x=b(mod 2k) ->  c*x+2k*y=b-a 求这个方程对于x,y有没有整数解. 这个只要学过拓展欧几里得(好像有的叫扩展欧几里德QA ...