@Controller,标记在类头,意为控制器
@Controller("userController") -> 别名
public class UserController { }
@Service,标记在类头,意为业务层
@Service("userServiceImpl") -> 别名
public class UserServiceImpl implements IUserService { }
@RequestMapping,标记在类头或方法头,在控制层使用
@RequestMapping("/user")
public class UserController {
@RequestMapping(method = RequestMethod.POST, value = "/insert")
public void insert() {
User user = new User();
mUserService.insert(user);
}
}
@RequestMapping("/list.html") -> 伪静态
public String list() {} -> 返回类型为String
@ResponseBody,标记在类头,在控制层使用
@ResponseBody -> 将数据以Json格式返回
public User insertUser() {}
@RequestParam,请求参数,在控制层使用
public void param() {
@RequestParam(required = false,value="name")String name -> 明确请求参数名称
@RequestParam Map<String,Object> map -> 接收所有参数
required属性表示传入的参数是否可为空
value属性表示请求参数的名称
defaultValue属性表示请求参数为空时,赋予参数的属性值
}
@PathVariable,在控制层使用
@RequestMapping("/base/{id}.html") -> 从请求路径里获取值
public String base(@PathVariable int id) {
将路径里{id}的值赋予给参数id
}
@Param,在持久层使用
当传参数量大于二时,MyBatis并不能识别到多个传参,因此用@Param标记
List<User> select(@Param("name") String name,@Param("pass")String pass);
当传参为基本类型时,没有Getter和Setter方法,在MyBatis中使用if函数判断空或者比较大小时,
会出现错误,因此要使用@Param标记
List<User> select(@Param("id") int id);
@Value,在控制层使用
@Value(value="${url}") -> 从配置文件中读取名为url的值
private String url;
url = www.baidu.com -> 配置文件以键值对的方式存储
<context:property-placeholder location="classpath:system.properties"/> -> 在SpringMVC配置文件中加载资源文件
${random.*} -> SpringBoot配置类生成随机数
* -> value(String)、int(int)、long(long)、uuid(String)
url = ${random.value}、@value("${url}") || @value("${random.value}")
@Autowired和@Qualifier,在控制层或业务层使用
@Autowired(required = false)
@Qualifier("serviceImpl") -> 通过别名注入Bean
private IService mService; -> 动态代理生成,映射Json会出错
@Component -> 非Spring管理环境获取Bean
public class SpringUtils implements BeanFactoryPostProcessor{
private static ConfigurableListableBeanFactory beanFactory; -> Spring应用上下文环境
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
SpringUtils.beanFactory = beanFactory;
SpringUtils.beanFactory.getBean(...); -> 获取动态代理对象
}
}
@Component -> 非Spring管理环境获取Bean
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
SpringUtils.applicationContext.getBean(...); -> 获取动态代理对象
}
}
@Component -> Spring容器启动完成后初始化操作
public class CustomApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
}
}
@Component -> Spring容器启动完成后初始化操作
public class CustomCommandLineRunner implements CommandLineRunner{
@Override
public void run(String... args) throws Exception {
}
}
@ModelAttribute,在控制层使用
1、修饰方法,会在当前控制器每个方法请求前执行
@ModelAttribute("user") -> 别名默认为类名,第一个字母小写
public User getUser(){ -> 将返回值添加进Model中,在requestScope获取
return new User();
}
2、修饰入参,Spring的入参对象都是先从请求域中查找,若存在,获取该对象,将请求地址的参数赋予到该对象的属性中,若不存在,通过动态代理创建一个新的对象,再把请求地址的参数赋予到这个对象中。
public int insertUser(@ModelAttribute("user")User user){
return 0;
}
@CookieValue,在控制层使用
public Integer getUserId(@CookieValue("uid")Integer uid){
return uid; -> 从Cookie中获取名为uid的value
}
@RequestHeader,在控制层使用
public String getHeader(@RequestHeader("Accept-Language")String al){
return al; -> 从请求头中获取名为Accept-Language的value
}
@SessionAttributes,在控制层使用,标记在类头
@SessionAttributes(value = {"user"},types = {User.class}) -> 多请求属性共享
public class SessionController {
public Map<String,Object> session(Map<String,Object> map){
1、SessionAttributes在请求域中查找与value值相同的key的属性
map.put("user",new User()); -> key与SessionAttributes的value相同
2、SessionAttributes在请求域中查找属性的类型与types相同的属性
map.put("name","wjx"); -> wjx的属性类型与SessionAttributes的types相同
3、将所有符合条件的属性值以key-value形式存入Session,实现共享
return map;
}
public User session(@SessionAttribute("user") User user){
return user; -> 从Session中获取属性user(session.getAttribute(user))
}
}
@Transactional,在业务层使用
@Transactional -> 所有方法纳入事务管理(类头)
public class UserServiceImpl implements IUserService {
@Transactional -> 当前方法纳入事务管理(方法头)
问题:事务对非public修饰的方法不生效
问题:事务对自调用(非事务方法调用事务方法)不生效
解答:使用AspectJ取代SpringAOP代理(造成原因)
public int insertUser(User user) {
return mUserMapper.insertUser(user);
}
1、Propagation.REQUIRED
当前存在事务,则加入该事务。当前不存在事务,则创建一个新的事务。
2、Propagation.SUPPORTS
当前存在事务,则加入该事务。当前不存在事务,以非事务的方式继续运行。
3、Propagation.MANDATORY
当前存在事务,则加入该事务。当前不存在事务,则抛出异常。
4、Propagation.REQUIRES_NEW
重新创建一个新的事务,如果当前存在事务,暂停当前的事务。
5、Propagation.NOT_SUPPORTED
以非事务的方式运行,如果当前存在事务,暂停当前的事务。
6、Propagation.NEVER
以非事务的方式运行,如果当前存在事务,则抛出异常。
7、Propagation.NESTED
当前存在事务,则创建子事务并加入该事务。当前不存在事务,则创建一个新的事务。
8、isolation = Isolation.DEFAULT
事务的隔离级别
9、timeout=360000
事务的超时时间,默认值为-1。超出时间限制,事务没有完成,自动回滚事务。
10、rollbackFor=Exception.class
指定事务回滚的异常类型,可以指定多个异常类型。
11、noRollbackFor=Exception.class
指定事务不回滚的异常类型,可以指定多个异常类型。
12、readOnly = true
指定事务的读(select)写(insert、update、delete)。
13、TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
编程式实现手动回滚事务。
14、Object point = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
编程式创建事务保存点
TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(point);
编程式回滚到事务保存点
TransactionAspectSupport.currentTransactionStatus().releaseSavepoint(point);
编程式释放事务保存点
}
@(Rest)ControllerAdvice和@ExceptionHandler
@ControllerAdvice
public class WebExceptionHandler { -> web error skip
@ExceptionHandler(value = Exception.class) -> 捕捉类型
public Object webErrorHandler(Exception e)throws Exception{
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("exception",e);
modelAndView.setViewName("error");
return modelAndView;
}
}
@RestControllerAdvice
public class AjaxExceptionHandler { -> ajax error skip
@ExceptionHandler(value = Exception.class) -> 捕捉类型
public Map<String,Object> ajaxErrorHandler(Exception e)throws Exception{
Map<String,Object> map = new HashMap<>();
map.put("exception",e);
return map;
}
}
@Component和@Resource
@Component -> 作为组件引入Spring容器
public class JedisUtil {}
@Resource("jedisUtil") -> 动态代理生成对象
private JedisUtil mJedisUtil;
@RequestAttribute,在控制层使用
public String request(@RequestAttribute("name") String name){
return name; -> 从request中获取属性name(request.getAttribute(name))
}
@Configuration和@Bean
@Configuration -> 效果等同Spring配置文件的<beans></beans>节点
public class Configuration{
@Bean -> 标注的方法等同<bean></bean>节点
public IService serviceImpl(){ -> 方法名对应配置文件的id
return new ServiceImpl(); -> 返回值对应配置文件的class
}
<bean id="serviceImpl" class="com.service.ServiceImpl"/>
}
@Component,标记在类头
@Component("component") -> 作为组件引入Spring容器,别名默认为开头字母小写
public class Component{
<bean id="component" class="com.pojo.Component"></bean>
}
@Deprecated,标记在类头
@Deprecated -> 指明该类废弃(类名有删除线)
public class Deprecated{}
@RequestBody,标记在请求参数
public String json(@RequestBody String json){
前端的参数以JSON格式传递给后端,POST方式提交,后端在请求体中获取参数
GET方式提交的参数,携带在请求头中,可用@RequestHeader提取信息
}
$.ajax({
type: "POST",
contentType: "application/json;charset=utf-8",
data: JSON.stringify(list),
dataType: "json",
url: '/ssm/user/export',
success: function (data) {
}
});
@JsonProperty,标记在实体类属性
@JsonProperty("name") -> JackJson
private String name; -> 返回JSON时,key为name
@JsonInclude,标记在实体类头
@JsonInclude(Include.NON_NULL)
public class JsonInclude{
private String name; -> 属性为空时不序列化
}
@TableField,标记在实体类属性
@TableField(exist = false,value="name") -> MyBatisPlus
private String name; -> 说明当前属性不是该实体类对应的表中的列
@Repository和@Mapper,标记在持久层
@Repository("userDao") -> 通过别名注入Bean
@Mapper -> 标记为持久层
public interface UserDao {}
@DateTimeFormat,标记在实体类属性
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date; -> 前端传字符串日期给后端接收
@JsonFormat,标记在实体类属性
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date date; -> 后端日期格式化展示给前端
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime localDateTime; -> 后端按格式接收前端日期
@Valid,标记在控制器入参
public User save(@Valid @RequestBody UserDto userDto, BindingResult bindingResult) {
if (bindingResult.hasFieldErrors() && bindingResult.getFieldError() != null) {
return Response.error(bindingResult.getFieldError().getDefaultMessage());
}
return mUserService.save(userDto);
}
public class UserDto {
@NotNull(message = "age can not be null")
private Long age;
@NotBlank(message = "name can not be blank")
private String name;
}
public class UserVo {
@Valid
private User user;
}
public class User {
@NotNull(message = "age can not be null")
private Long age;
@NotBlank(message = "name can not be blank")
private String name;
}
@Validated,标记在控制器类上
@Validated
public class UserController {
@GetMapping("/getUserById")
public User getUserById(@NotNull(message = "userId cannot be null") Long userId, BindingResult bindingResult) {}
}
Spring的隐式对象
Spring容器可以通过动态代理生成对象,如常见的request和response,这些对象会存在请求域中,在不同的方法中可以共享相同的对象,从而达到了隐式对象属性的共享。