@ConditionalOnExpression
@ConditionalOnExpression(“'true”) 当括号中的内容为true时 ,使用该注解的类被实例化
它可以和@Service、@Component、@Controller、@Repository 、@Bean 、@Configuration 等注解一起使用。可以通过SPEL 表达式、读取配置文件属性来让IOC容器选择性的扫描加入指定的某个Bean。而不是将所有实现类Bean都加入到IOC。简单来说就是按需加载,而不是全部加载。
@Bean
@ConditionalOnExpression("#{'true'.equals(environment['print.sql.log.enable'])}")
public SqlInterceptor myPlugin() {
return new SqlInterceptor();
}
@EnableDiscoveryClient
实现服务注册
@RequestParam的作用有三个
句子 | 解析 | 备注 |
---|---|---|
可以前端传递下划线数据,后端接受为驼峰 | eg: @RequestParam(value = “equip_id”)String equipId | |
可以规定其是否必须传递 | ||
可以赋默认值 | ||
可以在POST 中使用 |
@ConfigurationPropertiesScan
注解,用来主动扫描没有定义 Bean 的 @ConfigurationProperties,相当于一个总开关
@PathVariable
@PathVariable 修饰的路径参数,必须要有!!!
click
@ResponseStatus
作用就是为了改变HTTP响应的状态码
在RestControllerAdvice 中的统一异常处理器中
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public CallResultMsg sendErrorResponse_System(Exception exception){
if (exception instanceof UserDefinedException) {
return this.sendErrorResponse_UserDefined(exception);
}
ControllerAdvice 和 RestControllerAdvice的区别
@ControllerAdvice 和 @RestControllerAdvice都是对Controller进行增强的,可以全局捕获spring mvc抛的异常。
RestControllerAdvice = ControllerAdvice + ResponseBody
@RestControllerAdvice + @ExceptionHandler
对SpringMCV的接口的异常做统一的异常返回处理
通常–处理情况,我们也需要统一成上面的格式。如果我们在controller中通过try catch来处理异常的话,会出现一个问题就是每个函数里都加一个Try catch,代码会变的很乱。下面我们就通过spring boot的注解来省略掉controller中的try-catch 帮助我们来封装异常信息并返回给前端,
使用
annotations(),basePackageClasses(),
basePackages()或它的别名value() 可以被指定,以限定控制器
,以协助的特定子集。
当应用多个选择器时,应用OR逻辑 - 意味着所选的控制器应匹配至少一个选择器。
默认行为(即,如果没有任何选择器使用),
带@RestControllerAdvice注释的类将协助所有已知的控制器。
ResponseBodyAdvice
理解:此接口有beforeBodyWrite方法, 参数body是响应对象response中的响应体,那么我们就可以用此方法来对响应体做一些统一的操作。比如加密,签名等
Component
@RestControllerAdvice("com.zqsign.app.privatearbitrate.controller.remote")
public class LocalAuthResponseInterceptor implements ResponseBodyAdvice {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
/**
* 响应时添加签名字段
* 用**私钥加密
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
String bodyStr = JSON.toJSONString(body, SerializerFeature.MapSortField);
String sign = null;
if (body != null) {
sign = RsaSign.sign(bodyStr, ZqConfig.TENANT_PRIVATE_KEY);
}
Response resp = (Response) body;
ResponseModel responseModel = new ResponseModel();
responseModel.setCode(resp.getCode());
responseModel.setMessage(resp.getMessage());
responseModel.setData(resp.getData());
responseModel.setSign(sign);
return responseModel;
}
}
@RestControllerAdvice(“com.zqsign.app.privatearbitrate.controller.remote”):
表示com.zqsign.app.privatearbitrate.controller.remote
此包下的所有响应对象都会经过此拦截器,并对响应体加上签名。
@RequestBody
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);而最常用的使用请求体传参的无疑是POST请求了,所以使用@RequestBody接收数据时,一般都用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个
click me
@ExceptionHandler
注解中可以添加参数,参数是某个异常类的class,代表这个方法专门处理该类异常
可以用来统一处理方法抛出的异常
click me
@FunctionalInterface
1、该注解只能标记在"有且仅有一个抽象方法"的接口上。
2、JDK8接口中的静态方法和默认方法,都不算是抽象方法。
3、接口默认继承java.lang.Object,所以如果接口显示声明覆盖了Object中方法,那么也不算抽象方法。
4、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错。
@FunctionalInterface标记在接口上,“函数式接口”是指仅仅只包含一个抽象方法的接口。
@SneakyThrows
在日常开发中,@SneakyThrows用的并不多,因为只是将异常抛出throw,还是需要你在调用方法时对异常做处理。 它只是一个try-catch的简单写法:
@SneakyThrows可以用来偷偷抛出已检查的异常而不在方法的throws子句中实际声明这一点。
也能抛出RuntimeException
当然,应该谨慎使用这种有争议的能力。由lombok生成的代码不会忽略,包装,替换或以其他方式修改抛出的已检查异常; 它只是伪造了编译器。在JVM(类文件)级别,无论方法的throws子句如何,都可以抛出所有异常,无论是否检查,这就是为什么这样做的原因。
默认是最低优先级,值越小优先级越高 @Order
比如 CommandLineRunner 经常配合@Order进行使用;
package org.springframework.core.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Documented
public @interface Order {
int value() default 2147483647;
}
@ConditionalOnBean
当给定的在bean存在时,则实例化当前Bean,
这个bean可能由于某种原因而没有注册到ioc里,这时@ConditionalOnBean可以让当前bean也不进行注册
@ConditionalOnClass
当给定的类名在类路径上存在,则实例化当前Bean
@ConditionalOnMissingClass
当给定的类名在类路径上不存在,则实例化当前Bean
@ConditionalOnMissingBean
当给定的在bean不存在时,则实例化当前Bean,感觉这个是在多态环境下使用,当一个接口有多个实现类时,如果只希望它有一个实现类,那就在各个实现类上加上这个注解
@EnableAutoConfiguration
msg | 解析 | 备注 |
---|---|---|
@EnableAutoConfiguration 作用是从classpath中搜索所有META-INF/spring.factories配置文件,然后,将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration key对应的配置项加载到spring容器; | ||
@EnableAutoConfiguration 作用是从classpath中
搜索所有META-INF/spring.factories配置文件,然后,
将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration
key对应的配置项加载到spring容器;@EnableAutoConfiguration还可以进行排除,
排除方式有2中,一是根据class来排除(exclude),
二是根据class name(excludeName)来排除。在本项目配置中排除了DataSourceAutoConfiguration类
@EnableAutoConfiguration还可以进行排除,
排除方式有2中,一是根据class来排除(exclude),
二是根据class name(excludeName)来排除。在本项目配置中排除了DataSourceAutoConfiguration类
排除方式
@SpringBootApplication(exclude = {ElasticsearchRestClientAutoConfiguration.class})
global-key client 项目中的spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.jiediankeji.globalkeyclient.config.GlobalKeyClientAutoConfiguration
org.springframework.context.ApplicationListener=com.jiediankeji.globalkeyclient.listener.GlobalKeyClientApplicationListener
@ConditionalOnProperty
msg | 解析 | 备注 |
---|---|---|
环境控制下的Bean的注入 | link | |
value 参考kudu-starter
name属性,name用来从application.properties中读取某个属性值
value 数组,获取对应property名称的值,与name不可同时使用
matchIfMissing
/**
*该属性为true时,配置文件中缺少对应的value或name的对应的属性值,也会注入成功
*/
boolean matchIfMissing() default false;
@Qualifier
在Controller中需要注入service那么我的这个server有两个实现类如何区分开这两个impl
解决:Qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的,添加@Qualifier注解,需要注意的是@Qualifier的参数名称为我们之前定义@Service注解的名称之一。
eg:
Qualifier用在本地变量上
@ConditionalOnClass
用在方法上
@ConditionalOnClass(某个class存在,才会实例化一个Bean)
eg1
当KuduProperties 存在,并存在容器中,KuduClient才会创建
eg2
@Congfiguration
proxyBeanMethods属性默认值是true,也就是说该配置类会被代理(CGLIB),在同一个配置文件中调用其它被@Bean注解标注的方法获取对象时会直接从IOC容器之中获取;
proxyBeanMethods 配置类是用来指定@Bean注解标注的方法是否使用代理,默认是true使用代理,直接从IOC容器之中取得对象;如果设置为false,也就是不使用注解,每次调用@Bean标注的方法获取到的对象和IOC容器中的都不一样,是一个新的对象,所以我们可以将此属性设置为false来提高性能;
用cglib代理增强,bean是单例的,@Bean方法调用生成实例时,如果已经存在这个bean,直接返回
@Bean
@Bean(destroyMethod = “close”)
[click](https://www.cnblogs.com/feiyu127/p/7700090.html) ## @Import@Import通过快速导入的方式实现把实例加入spring的IOC容器中
@Import注解的作用和在使用spring的xml配置时用到的类似。但应注意是@Import在使用时,
必须要保证能被IOC容器扫描到,所以通常它会和@Configuration或者@ComponentScan配套使用。
@Import在使用时可以声明在JAVA类上,或者作为元注解使用(即声明在其他注解上)
@Import注解就是之前xml配置中的import标签,可以用于依赖第三方包中bean的配置和加载
在4.2之前只支持导入配置类
在4.2,@Import注解支持导入普通的java类,并将其声明成一个bean
分析类注释得出结论:
声明一个bean
导入@Configuration注解的配置类
导入ImportSelector的实现类
导入ImportBeanDefinitionRegistrar的实现类
读取yml文件
ConfigurationProperties 作用
吸取yml中的内容,但是必须配合 @component 或者 @EnableConfigurationProperties,才能注入到容器
@ConfigurationProperties
@EnableConfigurationProperties注解的作用是:使使用 @ConfigurationProperties 注解的类生效
link
常规玩法
使用@ConfigurationProperties + @Configuration 导入配置到容器,@Configuration 有@Compont
@RefreshScope
@Configuration
@ConfigurationProperties(prefix = "common")
@Data
public class CommonConfig {
/**
* 每次任务最大同步数量
*/
private Integer maxSyncTaskNum;
}
@Value
@Autowired
Java变量的初始化顺序
-> 静态变量或静态语句块
–> 实例变量或初始化语句块
–> 构造方法
–> @Autowired
二、区别
明确了java变量的初始化顺序就能确定一点。假如我们通过seter方式注入bean,但是又在实例变量或者初始化块中使用bean的方法,这样就会出现空指针的问题。因为@autowired写在变量上的注入要等到类完全加载完才会将相应的bean注入。
总的来说,区别就是加载顺序的不同。
Autowired,放在构造器上,两点,一是对你的参数进行注入,第二是在使用这个类之前,初始化构造器中的代码,给上面的参数赋值,举例如下:
构造函数注入的方式:
public class TestController {
private final TestService testService;
@Autowired
public TestController(TestService testService) {
this.testService = testService;
}
…
}
@RequestLine
@RequestLine与其它请求不同,只需要简单写请求方式和路径就能达到请求其它服务的目的
@FeignClient(value = "feign-server",configuration = FeignConfig.class) //需要一个配置文件
public interface TestService {
@RequestLine("POST /feign/test") //对应请求方式和路径
String feign(@RequestBody UserDO userDO);
}
requestMapping
requestMapping 这个狗东西兼容了POST和GET
@ServletComponentScan
SpringBootApplication 上使用@ServletComponentScan 注解后
Servlet可以直接通过@WebServlet注解自动注册
Filter可以直接通过@WebFilter注解自动注册
Listener可以直接通过@WebListener 注解自动注册