1.@SpringCloudApplication
@SpringCloudApplication @EnableFeignClients @MapperScan("com.xx.common.domain.mapper") @ComponentScan({"com.xx.common", "com.xx.api"}) public class ApiApp { public static void main(String[] args) { SpringApplication.run(ApiApp.class, args); } } @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker public @interface SpringCloudApplication { }
2.@EnableFeignClients
通过EnableFeignClients调用其他服务的api // 步骤1 @SpringCloudApplication @EnableFeignClients @MapperScan("com.xx.common.domain.mapper") @ComponentScan({"com.xx.common", "com.xx.api"}) public class ApiApp { public static void main(String[] args) { SpringApplication.run(XxApiApp.class, args); } } // 步骤2 @FeignClient(name = "xx-proxy", fallback = XxApiClientFallback.class) public interface XxApiClient { @PostMapping(value = "/app1/list") Resp<XxRes> get_app1_list(@RequestBody XxReq req); @PostMapping(value = "/app2/list") Resp<XxRes> get_app2_list(@RequestBody XxReq req); ...... } // 步骤3 @RestController @RequestMapping("/app1") public class XxController { @Resource private XxBiz xxBiz; @PostMapping(value = "/list") public Resp<XxRes> getList(@RequestBody XxReq req) { return xxBiz.list(req); } ...... }
3.@MapperScan
之前是,直接在Mapper类上面添加注解@Mapper,这种方式要求每一个mapper类都需要添加此注解,麻烦。通过使用@MapperScan可以指定要扫描的Mapper类的包的路径,比如: @SpringCloudApplication @EnableFeignClients @MapperScan("com.xx.common.domain.mapper") @ComponentScan({"com.xx.common", "com.xx.api"}) public class ApiApp { public static void main(String[] args) { SpringApplication.run(XxApiApp.class, args); } }
4.@ComponentScan
@ComponentScan告诉Spring 哪个packages 的用注解标识的类 会被spring自动扫描并且装入bean容器。 用于指定包的扫描路径。用于代替spring的xml配置文件中的<context:componet-scan base-package=""/>标签。 spring就会去自动扫描base-package对应的路径或者该路径的子包下面的带有 @Service @Component @Repository @Controller注解的java文件。
5.@Configuration
对应spring xml配置文件。它就是JavaConfig形式的Spring Ioc容器的配置类使用的那个@Configuration,SpringBoot社区推荐使用基于JavaConfig的配置形式,所以,这里的启动类标注了@Configuration之后,本身其实也是一个IoC容器的配置类。
6.WebMvcConfigurer
SpringBoot1.x->SpringBoot2.0版本,使用的系统内还是存在一些兼容性的问题,有很多变化!!! SpringBoot1.x中可以使用WebMvcConfigurerAdapter抽象类来处理SpringMVC相关的配置; SpringBoot2.0版本最低支持 JDK1.8环境,在JDK1.8引入了特殊的关键字default,该关键字配置在interface接口的方法时子类可以不去实现该方法,相当于抽象类内已经实现的接口方法。 // 方式一:JavaBean配置WebMvcConfigurer @Configuration public class WebJavaBeanConfiguration { @Autowired private LogInterceptor logInterceptor; /** 实例化WebMvcConfigurer接口 */ @Bean public WebMvcConfigurer webMvcConfigurer() { return new WebMvcConfigurer() { /** 添加拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(logInterceptor).addPathPatterns("/**"); } }; } } @Component public class LogInterceptor implements HandlerInterceptor { /** logger instance */ static Logger logger = LoggerFactory.getLogger(LogInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { logger.info("请求路径:{}", request.getRequestURI()); return true; } } // 方式二:实现类配置WebMvcConfigurer @Configuration public class InterceptorConfigurer implements WebMvcConfigurer { @Autowired private LogInterceptor logInterceptor; /** * 重写添加拦截器方法并添加配置拦截器 * @param registry */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(logInterceptor).addPathPatterns("/**"); } }
7.ClientHttpRequestFactory
RestTemplate类位于org.springframework.web.client包中,提供Http的各类方法:如Get,Head,Post,Put,Delete等,RestTemplate有两个构造方法,分别是: public RestTemplate() { } public RestTemplate(ClientHttpRequestFactory requestFactory) { this(); setRequestFactory(requestFactory); } 第一个进行默认初始化,需求中我们需要对请求超时进行设置并能够对超时进行后续处理,第一个构造方法,我们无法控制超时时间 第二个构造中的ClientHttpRequestFactory接口的实现类中存在timeout属性,因此选用第二个构造方法。 在spring配置文件中进行如下配置: // 一、配置方式 <!-- 配置RestTemplate --> <!--Http client Factory--> <bean id="httpClientFactory" class="org.springframework.http.client.SimpleClientHttpRequestFactory"> <property name="connectTimeout" value="${connectTimeout}"/> <property name="readTimeout" value="${readTimeout}"/> </bean> <!--RestTemplate--> <bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> <constructor-arg ref="httpClientFactory"/> </bean> // 二、注解方式 @Configuration public class RestTemplateConfig { @Bean public ClientHttpRequestFactory clientHttpRequestFactory() { SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); factory.setReadTimeout(5000); factory.setConnectTimeout(5000); return factory; } @Bean public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) { return new RestTemplate(clientHttpRequestFactory); } } 注意:ClientHttpRequestFactory 接口有4个实现类,分别是: 1.AbstractClientHttpRequestFactoryWrapper 用来装配其他request factory的抽象类。 2.CommonsClientHttpRequestFactory 允许用户配置带有认证和http连接池的httpclient,已废弃,推荐用HttpComponentsClientHttpRequestFactory。 3.HttpComponentsClientHttpRequestFactory 同2. 4.SimpleClientHttpRequestFactory 接口的一个简单实现,可配置proxy,connectTimeout,readTimeout等参数。 本文中使用的是第4个实现,具体的根据个人需求再选在使用哪个。
8.@EnableResourceServer
@EnableResourceServer注释用于告诉微服务它是受保护的资源。
9.@Retention@Documented@Inherited
@Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值: 1.RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略 2.RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略 3.RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射 @Documented 注解表明这个注解应该被 javadoc工具记录. 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中. @Inherited这是一个稍微复杂的注解类型. 它指明被注解的类会自动继承. 更具体地说,如果定义注解时使用了 @Inherited 标记,然后用定义的注解来标注另一个父类, 父类又有一个子类(subclass),则父类的所有属性将被继承到它的子类中. @Inherited public @interface MyParentObject { boolean isInherited() default true; String doSomething() default "Do what?"; } @MyParentObject public Class MyChildObject { }
10.@EnableGlobalMethodSecurity
Spring Security默认是禁用注解的,要想开启注解,需要在继承WebSecurityConfigurerAdapter的类上加@EnableGlobalMethodSecurity注解,来判断用户对某个控制层的方法是否具有访问权限。 @Configuration @EnableWebSecurity -> 可以分解到Application.java @EnableGlobalMethodSecurity(prePostEnabled = true) public class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter { ........................... } @PreAuthorize("hasRole('admin')") @RequestMapping(value = "/user/", method = RequestMethod.GET) @ResponseBody public List<User> listAllUsers() { List<User> users = userService.findAll(); if(users.isEmpty()){ return null; } return users; }
11.@Import
@Import注解就是之前xml配置中的import标签,可以用于依赖第三方包中bean的配置和加载 在4.2之前只支持导入配置类 在4.2,@Import注解支持导入普通的java类,并将其声明成一个bean public class DemoService { public void doSomething(){ System.out.println("ok"); } } import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration @Import(DemoService.class)//在spring 4.2之前是不不支持的 public class DemoConfig { } import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com..example"); DemoService ds = context.getBean(DemoService.class); ds.doSomething(); } }
12.@LoadBalanced
@LoadBalanced注释告诉Spring Cloud创建一个Ribbon支持的RestTemplate类。 @SpringBootApplication @EnableDiscoveryClient // 使用Ribbon时,这两个注释不需要 @EnableFeignClients public class Application { @LoadBalanced @Bean public RestTemplate getRestTemplate(){ return new RestTemplate(); } }
13.@CacheEvict
@CacheEvict是用来标注在需要清除缓存元素的方法或类上的。当标记在一个类上时表示其中所有的方法的执行都会触发缓存的清除操作。@CacheEvict可以指定的属性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的语义与@Cacheable对应的属性类似。
value:表示清除操作是发生在哪些Cache上的(对应Cache的名称);
key:表示需要清除的是哪个key,如未指定则会使用默认策略生成的key;
condition:表示清除操作发生的条件。
下面我们来介绍一下新出现的两个属性allEntries和beforeInvocation。
从3.1开始,Spring引入了对Cache的支持。其使用方法和原理都类似于Spring对事务管理的支持。Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该方法参数和返回结果作为一个键值对存放在缓存中,等到下次利用同样的参数来调用该方法时将不再执行该方法,而是直接从缓存中获取结果进行返回。所以在使用Spring Cache的时候我们要保证我们缓存的方法对于相同的方法参数要有相同的返回结果。
14.@lombok
lombok 的官方网址:http://projectlombok.org/ lombok 提供的注解不多,可以参考官方视频的讲解和官方文档。 Lombok 注解在线帮助文档:http://projectlombok.org/features/index. 下面介绍几个我常用的 lombok 注解: @Data:注解在类上;提供类所有属性的 getting 和 setting 方法,此外还提供了equals、canEqual、hashCode、toString 方法 @Setter:注解在属性上;为属性提供 setting 方法 @Getter:注解在属性上;为属性提供 getting 方法 @Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象 @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法 @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法 @Data相当于@Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode这5个注解的合集。 通过官方文档,可以得知,当使用@Data注解时,则有了@EqualsAndHashCode注解,那么就会在此类中存在equals(Object other) 和 hashCode()方法,且不会使用父类的属性,这就导致了可能的问题。 修复此问题的方法很简单: 1.使用@Getter @Setter @ToString代替@Data并且自定义equals(Object other) 和 hashCode()方法,比如有些类只需要判断主键id是否相等即足矣。 2.或者使用在使用@Data时同时加上@EqualsAndHashCode(callSuper=true)注解。