本篇随笔将对 Spring Boot 中的经常使用注解作一个简单的整理归档,写做顺序将从启动类开始并逐步向内外扩展,目的即为了分享也为了方便本身往后的回顾与查阅。
java
启动类示例以下:spring
@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 容器中,定义以下:app
@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 容器中。ide
测试类示例以下:单元测试
@RunWith(SpringRunner.class) @SpringBootTest public class ApplicationTests { @Test public void contextLoads() { } }
@RunWith(SpringRunner.class) 翻译一下就是使用 Spring 的 IoC 容器运行测试;@SpringBootTest 建立了 SpringApplication 的上下文;@Test 标注测试方法。在此推荐阅读 “SpringBoot单元测试” ,写得很详细,我就再也不赘述了,待有空补几篇复杂测试的案例分析。测试
他们是在 Spring Boot 中轻松实现面向接口编程的关键,一个用于逻辑层,一个用于数据层,示例以下:this
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>
标注组件,能够做用在任何层次。
控制器示例以下:
@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 从参数中取值。
示例以下:
@ControllerAdvice public class GlobalException { @ResponseBody @ExceptionHandler public String processException(Exception e) { return "error: " + e.getMessage(); } }
没啥好说的,@ExceptionHandler 能够过滤具体的异常类型:@ExceptionHandler(Exception.class)
经过 @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()); } }
@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。
个人公众号《有刻》,咱们共同成长!