Spring常用注解
HTTP相关注解
url请求参数:
@RequestBody :
- @RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
@RequestParam:
- 值得注意的属性:value 、 required
- 1、可以对传入参数指定参数名
1 @RequestParam String inputStr
2 // 下面的对传入参数指定为aa,如果前端不传aa参数名,会报错
3 @RequestParam(value="aa") String inputStr
-
2、可以通过required=false或者true(默认)来要求@RequestParam配置的前端参数是否一定要传
// required=false表示不传的话,会给参数赋值为null,required=true就是必须要有 2 @RequestMapping("testRequestParam") 3 public String filesUpload(@RequestParam(value="aa", required=true) String inputStr, HttpServletRequest request)
-
3、如果@requestParam注解的参数是int类型,并且required=false,此时如果不传参数的话,会报错。原因是,required=false时,不传参数的话,会给参数赋值null,这样就会把null赋值给了int,因此会报错。
1 // required=false表示不传的话,会给参数赋值为null,required=true就是必须要有 2 @RequestMapping("testRequestParam") 3 public String filesUpload(@RequestParam(value="aa", required=false) int inputStr, HttpServletRequest request) 4 若是前端页面不传参的话,此处就会报错。当然可以用Integer代替int
所以接口的入参最好用包装类!!
-
4、可以用Map 来接受key-value参数,用@RequestParam 来注解,如
@RequestParam Map<String, ?> param
@RequestHeader
@ModelAttribute
public String test1(@ModelAttribute("user") UserModel user)
@Validated
public String save(@Validated @RequestBody ValidList<Su> listSu, BindingResult bindingResult)
@Validated 校验ValidList
常用的校验注解:注意,不要错用了异常类型,比如在int上不可用@size
@AssertFalse 校验false
@AssertTrue 校验true
@DecimalMax(value=,inclusive=) 小于等于value,
inclusive=true,是小于等于
@DecimalMin(value=,inclusive=) 与上类似
@Max(value=) 小于等于value
@Min(value=) 大于等于value
@NotNull 检查Null
@Past 检查日期
@Pattern(regex=,flag=) 正则
@Size(min=, max=) 字符串,集合,map限制大小
@Validate 对po实体类进行校验
而后,当输入不能满足条件是,就会抛出异常,而后统一由异常中心处理
也可以用BindingResult,但是用了这个后就必须手动处理异常,侵入了正常的逻辑过程,并不推荐.
// 校验参数是否为空
if (bindingResult.hasErrors()) {
return "error";
}
http请求:
@RequestMapping
-
@RequestMapping不仅支持标准的URL,还支持Ant风格和带{xxx}占位符的URL,下面的URL都是合法的:
•/user/*/login:匹配/user/aaa/login,/user/任意字符/login等
•/user//login:匹配/user/login,/user/aaa/bbb/login 等
•/user/login??:匹配/user/loginAA,/user/loginbb 等
•/user/{userId}:匹配/user/123,/user/234 等
•/user//{userId}:匹配/user/aaa/bbb/123,/user/aaa/234等这些占位符需要用pathvariable绑定后使用
容器组件注册
@Scope
配置Bean的作用域
- ConfigurableBeanFactory#SCOPE_PROTOTYPE -->多实例,需要创建时加载
- ConfigurableBeanFactory#SCOPE_SINGLETON -->单实例,容器启动时加载(默认)
@Lazy
针对单实例的Bean懒加载,容器启动的时候不加载Bean,只有在向容器获取单实例Bean的时候才向容器注册一个单实例Bean,然后被使用
@Conditional
@Conditional,按照一定的条件进行判断,满足条件给容器注册Bean.
用法:可用于类或者方法上 @Conditional({WindowsCondition.class})
@Conditional({WindowsCondition.class})
@Bean("bill")
public Person person01() {
return new Person("Bill Gates", 60);
}
public class WindowsCondition implements Condition {
/**
*
* @param context 判断条件能使用的上下文
* @param metadata 注释信息
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String osName = environment.getProperty("os.name");
return "Windows".equalsIgnoreCase(osName);
}
}
容器注册组件的方式
包扫描@ComponentScan+组件标注@Controller,@Service,@Repository,@Component
@Bean
[导入的第三方包的组件]
@Import
[组件]
@Import
(要导入到容器中的组件,容器就会自动注册一个id默认未全限定类名的实例)ImportSelector
:返回需要导入的组件的全类名数组,解决的问题是批量导入组件,且更便于分组管理。用的较多。ImportBeanDefinitionRegistrar
:手动注册Bean到容器中
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param importingClassMetadata 当前类的注解信息
* @param registry BeanDefinition注册类,把所有添加到容器中的bean,
* 调用BeanDefinitionRegistry.registerBeanDefinition手动注册
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
RootBeanDefinition rainBow = new RootBeanDefinition(Rainbow.class);
registry.registerBeanDefinition("rainBow", rainBow);
}
}
使用Spring提供的FactoryBean
和其他框架做整合时用得较多
- 默认获取到的是工厂bean调用getObject返回的对象
/**
* 工厂Bean在容器中注册的是工厂创建的对象实例
* 这里返回的虽然是{@see ColorFactory},但实际再容器中注册的是{@see Color},
* 注册到容器中会调用ColorFactory.getObject方法
*/
@Bean
public ColorFactory color() {
return new ColorFactory();
}
public class ColorFactory implements FactoryBean<Color> {
// 返回Color对象,这个对象会添加到容器中
@Override
public Color getObject() throws Exception {
System.out.println("getObject...");
return new Color();
}
// 返回对象的类型
@Override
public Class<?> getObjectType() {
return Color.class;
}
// true:单实例;false:多实例
@Override
public boolean isSingleton() {
return true;
}
}
- 要获取工厂bean本身,要在id前面加一个&
@Test
@DisplayName("测试FactoryBean的用法来注册Bean到容器")
public void testFactoryBean() {
Object color1 = context.getBean("&color");
System.out.println("color的类型:" + color1.getClass());
}
输出:
color的类型:class com.test_space.ColorFactory
组件生命周期
Bean的生命周期
- bean创建--初始化--销毁的过程
容器管理bean的生命周期
我们可以自定义初始化和销毁方法;容器会在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
- 构造(对象创建):
- 单实例:再容器启动的时候创建
- 多实例:每次获取实例的时候创建
- 初始化:
- 对象创建完成,并赋值好,调用初始化方法
- 单实例:容器启动之后初始化
- 多实例:每次获取实例的时候初始化
- 对象创建完成,并赋值好,调用初始化方法
- 销毁:
- 单实例:容器关闭的时候
- 多实例:容器不管理多实例的bean,容器不会调用销毁方法,需要手动销毁
1.制定初始化和销毁方法
通过@Bean指定init-method和destroy-method
2.通过让Bean实现InitializingBean,DisposableBean接口来初始化和销毁
3.使用JSR250:[推荐使用]
@PostConstruct:再Bean创建完成并赋值结束之后,执行初始化方法
@PreDestroy:容器销毁bean之前通知清理
4.BeanPostProcessor:Bean后置处理器
在bean初始化前后进行一些处理工作:
- postProcessBeforeInitialization:在初始化之前工作postProcessAfterInitialization:在初始化之后工作
顺序:construct->postProcessBeforeInitialization->init->postProcessAfterInitialization
事务:
@Transactional:
### |
---|
- |
- |
@Transactional 注解也可以添加到类级别上。当把@Transactional 注解放在类级别时,表示所有该类的公共方法都配置相同的事务属性信息。当类级别配置了@Transactional,方法级别也配置了@Transactional,应用程序会以方法级别的事务属性信息来管理事务,换言之,方法级别的事务属性信息会覆盖类级别的相关配置信息 |