一. spring
1. @Configuration
该注解用于注解配置类,注解源码继承了@Component,并且在value中别名了component的value
他不同于@Component的在于:该注解可以在类中生命多个@Bean的bean
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(annotation = Component.class)
String value() default "";
boolean proxyBeanMethods() default true;
}
其中proxyBeanMethods属性是一个设置为是否为单例的属性
- Full(proxyBeanMethods = true) :proxyBeanMethods参数设置为true时即为:Full 全模式。 该模式下注入容器中的同一个组件无论被取出多少次都是同一个bean实例,即单实例对象,在该模式下SpringBoot每次启动都会判断检查容器中是否存在该组件
- Lite(proxyBeanMethods = false) :proxyBeanMethods参数设置为false时即为:Lite 轻量级模式。该模式下注入容器中的同一个组件无论被取出多少次都是不同的bean实例,即多实例对象,在该模式下SpringBoot每次启动会跳过检查容器中是否存在该组件
- 什么时候用Full全模式,什么时候用Lite轻量级模式?
- 当在你的同一个Configuration配置类中,注入到容器中的bean实例之间有依赖关系时,建议使用Full全模式
- 当在你的同一个Configuration配置类中,注入到容器中的bean实例之间没有依赖关系时,建议使用Lite轻量级模式,以提高springboot的启动速度和性能
2. @Conditional @ConditionalOnXXX
@Conditional(TestCondition.class)
该注解参数为Condition接口的实现类class数组,可以将实现了该接口的实现类写入,接口方法matches 返回true表示可以注入,false表示不可以注入,可实现动态选择注入bean
这句代码可以标注在类上面,表示该类下面的所有@Bean都会启用配置,也可以标注在方法上面,只是对该方法启用配置。
@ConditionalOnBean(仅仅在当前上下文中存在某个对象(bean)时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上(class文件存在根加载路径时),才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)
@ConditionalOnProperty
(
prefix = "spring.data.jdbc.repositories",
name = {"enabled"},
havingValue = "true",
matchIfMissing = true
)
在matchIfMissing为false时,如果name值为空,则返回false;如果name不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true,否则返回false。返回false也就意味着自动配置不会生效。
@Component
//@ConditionalOnClass(TestConditional1.class)
//@ConditionalOnBean(name = "ttttt")
//@ConditionalOnExpression("true")
//@Conditional({XXXX.class})
public class TestConditional2 {
@PostConstruct
public void test() {
System.out.println("TestConditional2 is create");
}
}
2.1 @Conditional实现自定义判断注解
spring context包下提供了一个注解@Conditional,上面的包装类注解都是基于该注解实现的,该注解中提供了一个参数value,是Condition接口的实现类,condition接口,就是用来实现判断拦截是否注册bean的接口。
如下: 就可以根据自定义规则决定是否注册bean
//声明一个bean,并设置根据自定义规则是否注入
@Configuration
@Conditional({
MyselfCondi.class
})
public class Bean3 {
}
//condition的实现类
public class MyselfCondi implements Condition {
/**
* 判断是否注册bean
* @param context spring的上线文,可以获取环境,bean工厂,注册工长等
* @param metadata 被加入conditional注解的类,可以获取他们的元数据
* @return .
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return false;
}
}
注意:bean的加载是需要先解析bean然后再注册的,此时conditional再解析bean时就会生效,所以如果要根据某个bean是否存在来决定是否注入,则需要生命conditional生效是在注册时生效,此时需要实现ConfigurationCondition接口,实例如下:
详情参考博客:http://www.itsoku.com/article/278
//根据当前项目的环境,决定启动拿个bean
public class MyselfCondition implements ConfigurationCondition {
//生命conditional是在bean注册时生效
@Override
public ConfigurationPhase getConfigurationPhase() {
return ConfigurationPhase.REGISTER_BEAN;
}
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String profile = context.getEnvironment().getActiveProfiles()[0];
AnnotationAttributes map = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(EnvCondition.class.getName()));
String value = map.getString("value");
return profile.equals(value);
}
}
3. @EnableConfigurationProperties
如果一个配置类只配置@ConfigurationProperties注解,而没有使用@Component,那么在IOC容器中是获取不到properties 配置文件转化的bean。说白了 @EnableConfigurationProperties 相当于把使用 @ConfigurationProperties 的类进行了一次注入。
测试发现 @ConfigurationProperties 与 @EnableConfigurationProperties 关系特别大。
4. @Lazy
Spring 中默认是非延迟加载Bean的,也就是提前把Bean初始化好,用的时候直接用. 优点是运行的时候比较快(提前初始化了,直接用). 缺点是启动慢和占用内存,因为要初始化很多Bean.
延迟加载是需要的时候再去初始化Bean. 优点是解约内存,启动快(不需要提前初始化Bean). 缺点是运行的时候比较慢(用的时候先要初始化才能用).
5. @LookUp
重写bean中的某个方法,并实现子类返回最新的bean对象
参考博客:https://blog.csdn.net/jerry010101/article/details/84997062
6.@Value
该注解用于将外部(配置文件)中的属性注入进来
6.1 @PropertySource:将某个properties文件引入上线文
@PropertySource(value = "classpath:application-test.properties")
@Configuration
public class ImportProperty {
}
6.2 使用@value注解:可以在属性上使用,也可以在构造器中使用
@Data
@Component
public class ValueTest {
// @Value("${myself.id}")
public Integer id;
// @Value("${myself.name}")
public Pojo name;
//当该属性未找到时,默认就是注入值:${myself.id},如果写法为在${myself.id:200},则默认就是:后面的值
public ValueTest(@Value("${myself.id:200}") Integer id, @Value("${myself.name:wht}") Pojo name) {
this.id = id;
this.name = name;
}
}
6.3 spring会自动完成一些类型转化,例如,分割的字符串可以转为数组集合等,如果要自定义实现类型转换,可以注册一个ConversionService来实现,如下:
@Configuration
public class ConverterConfig {
@Bean
public ConversionService conversionService() {
DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addConverter(new MyCustomConverter());
return conversionService;
}
}
//实现方式有多种,目前是通过实现converter接口完成类型转化
public class MyCustomConverter implements Converter<String, Pojo> {
@Override
public Pojo convert(String source) {
System.out.println("获取到的值是:"+ source);
return new Pojo(source);
}
}
7. @Profile("dev & test")
基于当前启动环境配置某个bean,本质上还是基于condition来实现的
@Bean
@Profile("dev")
public UserService userServiceImpl1() {
return new UserServiceImpl(userDao());
}
二. spring WEB mvc
1. @restControllerAdvice
该注解能够拦截controller的异常
2. @ExceptionHandler
该注解是指定异常拦截后的处理方法
3. @ResponseStatus
该注解指定response返回的状态
4. @InitBinder 字段绑定
该注解可以完成前端传过来的参数,进行指定的处理,例如传入的是2021-07-22,可以通过该注解将字符创解析为data类型进行绑定,一个controller中声明一个@InitBinder只对当前的controller生效,与exceptionHandler一样,如果全局生效,可以在@restControllerAdvice中声明,此注解实用性比较低,适用于只有一个参数、form参数、get参数。如果是接受的json参数,就涉及到了MVC中的参数解析(httpMessageConverter),如果需要类型转化,可以在这里进行处理
具体的使用介绍参考博客:https://blog.csdn.net/wang0907/article/details/108357696
5. @CrossOrigin 跨域请求
可以实现MVC的跨域请求,使用该注解注释在类或者方法上,或者配置一个全局的cors
在webMvcConfigurer中重写方法addCorsMappings即可。