SpringMVC 注解

@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,这些对象会存在请求域中,在不同的方法中可以共享相同的对象,从而达到了隐式对象属性的共享。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

  • 1、@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherS...
    jkian阅读 990评论 5 14
  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,223评论 1 92
  • 一、Spring2.5之前,我们都是通过实现Controller接口或其实现来定义我们的处理器类。二、Spring...
    work1Y阅读 312评论 0 0
  • 随着Annotation的流行,一些主流框架都加入了对Annotation的支持。使用Annotation能够简化...
    whoismy8023阅读 895评论 0 1
  • 今天我们和很多父母一样,礼拜天回家和孩子共度一个周末,一个星期没见,宝贝见了我们非常高兴,给爷爷奶奶说爸妈回来了,...
    嘉祺妈妈阅读 258评论 1 6