spring注解们

component
Service
Repository
Controller
RequestBody
ResponseBody
RestController
Resource
Autowired & Qualifier
RequestMapping
PathVariable
RequestParam
Scheduled
Param
JsonAlias & JsonProperty
JSONType
JSONField
Scope
PostConstruct & PreDestroy

在类上加上注解后,这个时候Spring还不认识它,这个时候需要把这个bean交给Spring来管理。有两种方式可以管理:

<!--基于注解的装配-->
<!--方式一-->
<bean class="com.HelloWorld"/>

<!--方式二-->
<context:component-scan base-package="com"/>
or
<!--如果只想扫描包下的@Controller或其他内容,则设置use-default-filters属性为false-->
<context:component-scan base-package="com" user-default-filters="false">
    <context:include-filter type="regex" expression="com.tan.*"/>
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

@component

作用:
Component是一个元注解,带此注解的类看为组件,当使用基于注解的配置和类路径扫描的时候,这些类就会被实例化
Component可以注解其他类注解,如:@Controller @Service @Repository @Aspect
把普通pojo实例化到spring容器中,相当于配置文件中的 <bean id="" class=""/>

位置:

属性:
不指定bean的名称,默认为类名首字母小写
指定bean的名称@Component(“xxx”)

细节:

@Component("demo")
public class Demo(){}

ApplicationContext ctx  = new ClassPathXmlApplicationContext("beans.xml");
Demo demo = (Demo)ctx.getBean("xxx");

@Service

作用:
springvmc采用经典的三层分层控制结构 :业务层
服务,注入dao,用于标注服务层,主要用来进行业务的逻辑处理

位置:

属性:
不指定bean的名称,默认为类名首字母小写
指定bean的名称@Service(“xxx”)


@Repository

作用:
springvmc采用经典的三层分层控制结构:持久层
用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件,实现dao访问

位置:

属性:
不指定bean的名称,默认为类名首字母小写
指定bean的名称@Repository(“xxx”)

细节:
先定义一个接口

public interface IIocDao{
    public void add();
}

然后实现类

//Dao层中定义了一些接口 表示将Dao类声明为bean
@Repository
public class IocDao implements IIocDao{
    public void add(){System.out.println("调用了Dao"); }
}

@Controller

作用:
springvmc采用经典的三层分层控制结构:控制层
使用它标记的类就是一个SpringMvc Controller对象,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。Controller只是定义了一个控制器类,而使用@RequestMapping注解的方法才是处理请求的处理器。
@controller 控制器(注入服务)

位置:

细节:

@Controller
public class HelloWorld{
	@RequestMapping(value="/demo")
	public String printHello() {
		return "hello";
	}

    @Autowried
    private IocSerevce service;
    public void add(){service.add(); }
}

@RequestBody

示例详细说明: 一定要看!
https://blog.csdn.net/justry_deng/article/details/80972817

作用:
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。

位置:
形参列表

属性:
当同时使用@RequestParam()和@RequestBody时,@RequestParam()指定的参数可以是普通元素、数组、集合、对象等等(即:当,@RequestBody 与@RequestParam()可以同时使用时,原SpringMVC接收参数的机制不变,只不过RequestBody 接收的是请求体里面的数据;而RequestParam接收的是key-value里面的参数,所以它会被切面进行处理从而可以用普通元素、数组、集合、对象等接收)。即:如果参数时放在请求体中,传入后台的话,那么后台要用@RequestBody才能接收到;如果不是放在请求体中的话,那么后台接收前台传过来的参数时,要用@RequestParam来接收,或则形参前什么也不写也能接收。

如果参数前写了@RequestParam(xxx),那么前端必须有对应的xxx名字才行(不管其是否有值,当然可以通 过设置该注解的required属性来调节是否必须传),如果没有xxx名的话,那么请求会出错,报400。

如果参数前不写@RequestParam(xxx)的话,那么就前端可以有可以没有对应的xxx名字才行,如果有xxx名的话,那么就会自动匹配;没有的话,请求也能正确发送。

这里与feign消费服务时不同;feign消费服务时,如果参数前什么也不写,那么会被默认是@RequestBody的。

细节:
如果后端参数是一个对象,且该参数前是以@RequestBody修饰的,那么前端传递json参数时,必须满足以下要求:

  • 后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为),实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。
  • json字符串中,如果value为"“的话,后端对应属性如果是String类型的,那么接受到的就是”",如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null。
  • json字符串中,如果value为null的话,后端对应收到的就是null。
  • 如果某个参数没有value的话,在传json字符串给后端时,要么干脆就不把该字段写到json字符串中;要么写value时, 必须有值,null 或"“都行。千万不能有类似"stature”:,这样的写法,如:
{
	"stature":,             // 错误
	"age":null,             // 正确
	"name":""               // 正确
}

@RequestBody与前端传过来的json数据的匹配规则
声明:根据不同的Content-Type等情况,Spring-MVC会采取不同的HttpMessageConverter实现来进行信息转换解析。下面介绍的是最常用的:前端以Content-Type 为application/json,传递json字符串数据;后端以@RequestBody模型接收数据的情况。

解析json数据大体流程概述:
Http传递请求体信息,最终会被封装进com.fasterxml.jackson.core.json.UTF8StreamJsonParser中(提示:Spring采CharacterEncodingFilter设置了默认编码为UTF-8),然后在public class BeanDeserializer extends BeanDeserializerBase implements java.io.Serializable中,通过public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) throws IOException方法进行解析


@ResponseBody

作用:
@ResponseBody的作用其实是将java对象转为json格式的数据。
@ResponseBody 表示该方法的返回结果直接写入 HTTP response body 中,一般在异步获取数据时使用【也就是AJAX】,在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。当方法上面没有写ResponseBody,底层会将方法的返回值封装为ModelAndView对象。

假如是字符串则直接将字符串写到客户端,假如是一个对象,此时会将对象转化为json串然后写到客户端。这里需要注意的是,如果返回对象,按utf-8编码。如果返回String,默认按iso8859-1编码,页面可能出现乱码。因此在注解中我们可以手动修改编码格式,例如@RequestMapping(value="/cat/query",produces=“text/html;charset=utf-8”),前面是请求的路径,后面是编码格式。

位置:
通常使用在控制层(controller)的方法上
controller类上

属性:

@ResponseBody
@RequestMapping("/login.do")
public Object login(@RequestBody User loginUuser, HttpSession session) {
	user = userService.checkLogin(loginUser);
	session.setAttribute("user", user);
	return new JsonResult(user);
}

细节:
在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。


@RestController

@Controller和@RestController的区别?
作用:
Spring中@RestController的作用等同于@Controller + @ResponseBody。

位置:

属性:

  1. 如果只是使用@RestController注解Controller,则Controller中的方法无法返回jsp页面,或者html,配置的视图解析器 InternalResourceViewResolver不起作用,返回的内容就是Return 里的内容。
  2. 如果需要返回到指定页面,则需要用 @Controller配合视图解析器InternalResourceViewResolver才行。
  3. 如果需要返回JSON,XML或自定义mediaType内容到页面,则需要在对应的方法上加上@ResponseBody注解。

@Resource

作用:
@Resource(name=“XXX”)//默认按name注入,可以通过name和type属性进行选择性注入,如名称无找到则通过类型注入
如果name属性一旦指定,就只会按照名称进行装配

位置:
字段,setter方法

属性:
@Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

细节:
@Resource 由jdk提供
@Resource装配顺序
  1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
  3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
  4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配;


@Autowired & @Qualifier

作用:
@Autowired 默认是按照byType进行注入的,如果发现找到多个bean,则,又按照byName方式比对,如果还有多个,则报出异常。
@Autowired也可以手动指定按照byName方式注入,使用@Qualifier标签,例如:
@Autowired () @Qualifier ( “baseDao” ) //一般作为@Autowired()的修饰用

位置:
@Autowired 可以对成员变量、方法以及构造函数进行注释,而 @Qualifier 的标注对象是成员变量、方法入参、构造函数入参。

属性:

细节:
@Autowired 由spring提供
@Autowired默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false)


@RequestMapping

作用:
使用@RequestMapping 注解映射请求路径
类级别的注解负责将一个特定(或符合某种模式)的请求路径映射到一个控制器上,同时通过方法级别的注解来细化映射,即
根据特定的HTTP请求方法(GET、POST 方法等)、HTTP请求中是否携带特定参数等条件,将请求映射到匹配的方法上

位置:
类,方法

属性:
映射单个URL@RequestMapping("")@RequestMapping(value="")
映射多个URL@RequestMapping({"",""})@RequestMapping(value={"",""})
路径开头是否加斜杠/均可,建议加上,如:@RequestMapping("/hello")

RequestMapping注解有六个属性,下面我们把她分成三类进行说明。

1、 value, method;
value: 指定请求的实际地址,指定的地址可以是URI Template 模式;
method: 指定请求的method类型, GET、POST、PUT、DELETE等;

2、 consumes,produces;
consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html;
produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

3、 params,headers;
params: 指定request中必须包含某些参数值是,才让该方法处理。
headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

细节:
@RequestMapping 一共有五种映射方式:
1、标准URL 映射
@RequestMapping("/hello")@RequestMapping({"/hello","/world"})

2、Ant 风格的 URL 映射

通配符说明
?匹配任何单字符
*匹配任意数量的字符(含 0 个)
**匹配任意数量的目录(含 0 个)

例如:

1@RequestMapping("/?/hello/")2@RequestMapping("/*/hello")3@RequestMapping("/**/hello")

3、占位符URL 映射
URL 中可以通过一个或多个 {} 占位符映射
例如:@RequestMapping("/user/{userId}/show")
可以通过@PathVariable("") 注解将占位符中的值绑定到方法参数上

/**
* 如果 URL 中的 userId 是纯数字,那么使用 @PathVariable
* 做绑定时,可以根据自己的需求将方法参数类型设置为 Long、Integer、String
*/
@RequestMapping("/user/{userId}/show")
public ModelAndView show(@PathVariable("userId") Long userId) {
	// 创建 ModelAndView 对象,并设置视图名称
	ModelAndView mv = new ModelAndView("show");
	// 添加模型数据
	mv.addObject("msg", "User ID:" + userId);
	return mv;
}

注意:@PathVariable("") 不能简写为 @PathVariable。因为在正常编译时,Java 类反射对象不包含方法的参数名称。如果在编
译时将Debug 打开(javac -debug=no),方法的参数名称才会记录到类中,此时才能简写,但不建议简写。

4、限制请求方法的URL 映射
在HTTP 请求中最常用的请求方法是 GET、POST,还有其他的一些方法,如:DELET、PUT、HEAD 等
限制请求方法,例如:@RequestMapping(value="/hello", method=RequestMethod.POST) 如需限制多个请求方法,以大括号包围,逗号隔开即可,例如:method={RequestMethod.GET,RequestMethod.POST}

5、限制请求参数的URL 映射
限制请求参数来映射URL,例如:@RequestMapping(value="/user/show", params="userId")即请求中必须带有userId 参数参数的限制规则如下:

1)params="userId"              //请求参数中必须包含 userId2)params="!userId"             //请求参数中不能包含 userId3)params="userId!=1"           //请求参数中必须包含 userId,但不能为 14)params={"userId","userName"} //必须包含 userId 和 userName 参数

//可以通过@RequestParam("") 注解将请求参数绑定到方法参数上
@RequestMapping(value="/user/show",params="userId")
public ModelAndView show(@RequestParam("userId") Long userId) {
	// 创建 ModelAndView 对象,并设置视图名称
	ModelAndView mv = new ModelAndView("show");
	// 添加模型数据
	mv.addObject("msg", "User ID:" + userId);
	return mv;
}

要注意@PathVariable("") 和 @RequestParam("") 的不同:
@PathVariable("") 是将 URL 中占位符处的值绑定到方法参数上
@RequestParam("") 是将 URL 后的请求参数绑定到方法参数上


@PathVariable

作用:
@PathVariable 映射 URL 绑定的占位符,带占位符的 URL 是 Spring3.0 新增的功能,该功能在SpringMVC 向 REST 目标挺进发展过程中具有里程碑的意义
@PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。

位置:
方法形参

属性:
@PathVariable只支持一个属性value,类型是为String,代表绑定的属性名称。默认不传递时,绑定为同名的形参。 应用时,在@RequestMapping请求路径中,将需要传递的参数用花括号{}括起来,然后,通过@PathVariable(“参数名称”)获取URL中对应的参数值。如果@PathVariable标明参数名称,则参数名称必须和URL中参数名称一致。

//@PathVariable可以用来映射URL中的占位符到目标方法的参数中
	@RequestMapping("/testPathVariable/{id}")
    public String testPathVariable(@PathVariable("id") Integer id)
    {
        System.out.println("testPathVariable:"+id);
        return SUCCESS;
    }
    
//@Description @PathVariable未标注参数名称,则被注解参数名必须后URL中的一致
//URI 模板 “/owners/{ownerId}” 指定了一个名叫 ownerId的变量。当控制器处理这个请求时,ownerId的值被设置为从 URI 中解析出来。比如,当请求 /viewUser/100 进来时,100 就是 ownerId的值
    @RequestMapping("/owners/{ownerId}")
    public Map<String, Object> viewUser2(@PathVariable Integer ownerId) {
        System.out.println("@PathVariable中 请求参数 ownerId = " + ownerId);
        return user;
    }

细节:
REST:即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。
1) 资源(Resources):网络上的一个实体,或者说是网络上的一个具体信息。它可以是一段文本、一张图片、一首歌曲、一种服务,总之就是一个具体的存在。可以用一个URI(统一资源定位符)指向它,每种资源对应一个特定的 URI 。要获取这个资源,访问它的URI就可以,因此 URI 即为每一个资源的独一无二的识别符。
2)表现层(Representation):把资源具体呈现出来的形式,叫做它的表现层(Representation)。比如,文本可以用 txt 格式表现,也可以用 HTML 格式、XML 格式、JSON 格式表现,甚至可以采用二进制格式。
3)状态转化(State Transfer):每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”(State Transfer)。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。具体说,就是 HTTP 协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。


@RequestParam

作用:
将请求参数绑定到你控制器的方法参数上

位置:
方法形参

属性:
@RequestParam(value=”参数名”, required=true/false, defaultValue=””)
1)value:请求参数名(必须配置)单一参数时,可简化如下:

   /**
    * @Description:    url参数中的name必须要和@RequestParam("name")一致
    */
    @GetMapping("edit1")
    public String edit1(@RequestParam("userId") Integer userId, Model model) {
        System.out.println("*******************" + userId);
        model.addAttribute("userId" , userId);
        return "/admin/ronghe/rongheMobileList/edit";
    }
    /**
     * @Description:    url参数中的name必须要和@RequestParam("name")一致
     *                  参数名字不一样
     */
    @GetMapping("edit2")
    public String edit2(@RequestParam("userId") Integer id, Model model) {
        System.out.println("*******************" + id);
        model.addAttribute("id" , id);
        return "/admin/ronghe/rongheMobileList/edit";
    }

(2)required:是否必需,默认为 true,即 请求中必须包含该参数,如果没有包含,将会抛出异常(可选配置)

   /**
    * @Description:    required = true时必须有参数id,否则会报错
    *                  required = false时参数id可不传,默认为null,所以此时参数类型不能为int
    */
    @GetMapping("edit3")
    public String edit3(@RequestParam(value = "id", required = true) Integer id, Model model) {
        System.out.println("*******************" + id);
        model.addAttribute("id" , id);
        return "/admin/ronghe/rongheMobileList/edit";
    }

(3)defaultValue:默认值,如果设置了该值,required 将自动设为 false,无论你是否配置了required,配置了什么值,都是 false;如果没有传该参数,就使用默认值(可选配置)

   /**
    * @Description:    设置defaultValue值时,required无论设置是何值,都默认为false
    */
    @GetMapping("edit4")
    public String edit4(@RequestParam(value = "id", required = false, defaultValue = "10") Integer id, Model model) {
        System.out.println("*******************" + id);
        model.addAttribute("id" , id);
        return "/admin/ronghe/rongheMobileList/edit";
    }

细节:
如果@requestParam注解的参数是int类型,并且required=false,此时如果不传参数的话,会报错。原因是,required=false时,不传参数的话,会给参数赋值null,这样就会把null赋值给了int,因此会报错。

 //接收的参数ids是数组
    @PostMapping("delete")
    @ResponseBody
    public RestResponse delete(@RequestParam(value = "ids[]", required = false) List<Long> ids) {
        if (null == ids) {
            return RestResponse.failure("ID不能为空" );
        }
        for (Long id : ids) {
            rongheMobileListService.deleteById(id);
        }
        return RestResponse.success();
    }
    
//接收的参数data是Map<String, Object>
    @PostMapping("entry")
    @ResponseBody
    public RestResponse add(@RequestParam(value = "data[mobile]") String mobile,
                            @RequestParam(value = "data[pro]") String pro,
                            @RequestParam(value = "data[realTime]", required = false) String realTime,
                            @RequestParam(value = "data[sjbm]", required = false) String sjbm,
                            @RequestParam(value = "data[sjmc]", required = false) String sjmc,
                            @RequestParam(value = "data[mobBm]", required = false) String mobBm,
                            @RequestParam(value = "data[mobMc]", required = false) String mobMc,
                            @RequestParam(value = "data[orderId]", required = false) String orderId,
                            @RequestParam(value = "data[sn]") String sn,
                            @RequestParam(value = "data[bakMobile]", required = false) String bakMobile) {
 
        return RestResponse.success();
    }

@Scheduled

在线cron表达式生成器:http://cron.qqe2.com/
在线cron执行时间计算: https://tool.lu/crontab/

作用:
spring-quartz定时器注解

位置:
方法

属性:
fixedRate 和 fixedDelay 的区别
fixedRate任务两次执行时间间隔是任务的开始点,而 fixedDelay 的间隔是前次任务的结束与下次任务的开始。

// fixedDelay 
// 上一次执行完毕时间点之后多长时间再执行。
@Scheduled(fixedDelay = 5000) //上一次执行完毕时间点之后5秒再执行

// fixedDelayString 
// 与fixedDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。
@Scheduled(fixedDelayString = "5000")  //上一次执行完毕时间点之后5秒再执行
//占位符的使用(配置文件中有配置:time.fixedDelay=5000):
    @Scheduled(fixedDelayString = "${time.fixedDelay}")
    void testFixedDelayString() {
        System.out.println("Execute at " + System.currentTimeMillis());
    }
    
// fixedRate
// 上一次开始执行时间点之后多长时间再执行。
@Scheduled(fixedRate = 5000) //上一次开始执行时间点之后5秒再执行

// fixedRateString
// 与fixedRate 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。

// initialDelay
// 第一次延迟多长时间后再执行。
@Scheduled(initialDelay=1000, fixedRate=5000) //第一次延迟1秒后执行,之后按fixedRate的规则每5秒执行一次

// initialDelayString
// 与initialDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。

配置方法:
1)在xml里加入task的命名空间

xmlns:task="http://www.springframework.org/schema/task"   
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.1.xsd  

2)启用注解驱动的定时任务

<task:annotation-driven scheduler="myScheduler"/>

3)配置定时任务的线程池
推荐配置线程池,若不配置多任务下会有问题。

<task:scheduler id="myScheduler" pool-size="5"/>  

4)写我们的定时任务
@Scheduled注解为定时任务,cron表达式里写执行的时机

import org.springframework.scheduling.annotation.Scheduled;  
import org.springframework.stereotype.Component;   
@Component  
public class quartzDemo{  
       @Scheduled(cron="0/10 * *  * * ? ")   //每10秒执行一次       
       public void demo(){ System.out.println("10s exec on time...");}      
}    

cron
在这里插入图片描述
Cron格式中特殊字符说明
在这里插入图片描述
注意:
LW:这两个字符可以连用,表示在某个月最后一个工作日,即最后一个星期五。
#:用于确定每个月第几个星期几,只能出现在DayofMonth域。例如在4#2,表示某月的第二个星期三。


@Param

作用:
@Param是MyBatis所提供的(org.apache.ibatis.annotations.Param),作为Dao层的注解,作用是用于传递参数,从而可以与SQL中的的字段名相对应,一般在2=<参数数<=5时使用最佳。

位置:
dao类方法入参

属性:

//在userDAO类中有这么一个函数:
public User selectByNameAndPwd(@Param("userName") String name,@Param("Password") String )

//在其对应的dao.xml文件中的查询语句则为:
select  username,password from user where username=${userName} and  password=${Password}

例子:
当只有一个参数,传进去一个值也只有一个参数可以匹配。当存在多个参数时,传进去的值就区分不开了,这时可以考虑用Map

public List<Role> findRoleByMap(Map<String, Object> parameter);

xml 配置

<select id="findRoleByMap" parameterType="map" resultType="role">
    SELECT id,name FROM t_role
    WHERE roleName=#{roleName}
    AND note=#{note}
<select>

测试文件

RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Map<String, Object> parameter = new HashMap<>();
parameter.put("roleName", "剑士");
parameter.put("note", "决战紫禁之巅");
List<Role> roles = roleMapper.findRolesByMap(parameter);

使用@Param
修改接口

public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);

这样就可以直接传入对应的值了。当然也可以使用Java Bean来传递多个参数,定义一个POJO

public class RoleParam {
    private String roleName;
    private String note;
}

接口变为:

public List<Role> findRoleByBean(RoleParam role);

这样对应的xml文件与1处的区别就在于id和parameterType发生了变化,id对应的方法和parameterType对应该类的权限定名。
而使用更多的场景可能是这样的,对应多个POJO

public List<Role> findRoleByMix(@Param("roleP") RoleParam role, @Param("permissionP") PermissionParam permission);

xml 注意此时并不需要写出parameterType属性,Mybatis会进行自动搜索。

<select id="findRoleByMix" resultType="role">
    SELECT id,name FROM t_role WHERE roleName=#{roleP.roleName} AND note=#{rolep.note} AND level=#{permissionP.level}
<select>

细节:
在不使用@Param注解的时候,函数的参数只能为一个,并且在查询语句取值时只能用#{},且其所属的类必须为Javabean,而使用@Param注解则可以使用多个参数,在查询语句中使用时可以使用#{}或者${}
@Param和@RequestParam没有关系


@JsonAlias & @JsonProperty

给出Controller中的测试类:
在这里插入图片描述

给出模型中的属性(setter/getter方法没截出来):
在这里插入图片描述
使用postman测试一下,示例:
在这里插入图片描述
在这里插入图片描述

全面的结论:
结论①:@JsonAlias注解,实现:json转模型时,使json中的特定key能转化为特定的模型属性;但是模型转json时,
对应的转换后的key仍然与属性名一致,见:上图示例中的name字段的请求与响应。
以下图进一步说明:
在这里插入图片描述
此时,json字符串转换为模型时,json中key为Name或为name123或为name的都能识别。

结论②:@JsonProperty注解,实现:json转模型时,使json中的特定key能转化为指定的模型属性;同样的,模
型转json时,对应的转换后的key为指定的key,见:示例中的motto字段的请求与响应。
以下图进一步说明:
在这里插入图片描述
此时,json字符串转换为模型时,key为MOTTO的能识别,但key为motto的不能识别。

结论③:@JsonAlias注解需要依赖于setter、getter,而@JsonProperty注解不需要。
结论④:在不考虑上述两个注解的一般情况下,key与属性匹配时,默认大小写敏感。
结论⑤:有多个相同的key的json字符串中,转换为模型时,会以相同的几个key中,排在最后的那个key的值给模
型属性复制,因为setter会覆盖原来的值。见示例中的gender属性。
结论⑥:后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面
的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值
符合(或可转换为)实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性。


@JSONType

作用:
定制序列化JSON

位置:

属性:
放在实体类中就会只装配列举的字段

@JSONType(includes = {"name","sex"})      //只装配 name, sex 
@JSONType(ignores ={"id", "sex"})         // 忽略 id , sex
@JSONType(orders={"id", "name", "sex"})   // 按照顺序装配

@JSONField

作用:
改变JSON输出的属性

位置:
方法(method),属性(field)以及方法中的参数(parameter)

属性:
JSONField中的name属性用来指定JSON串中key的名称

// @JSONField作用在Field时,其name不仅定义了输入key的名称,同时也定义了输出的名称。
public class Person {
    @JSONField(name = "name") // 注意观察生成的JSON串中name和age的区别
    private String name;
    @JSONField(name = "AGE")
    private String age;

    public String getName() { return name; }
    public void setName(String name) {this.name = name; }
    public String getAge() {return age;}
    public void setAge(String age) {this.age = age;}
}

// @JSONField也可以直接作用在get或set方法上
@JSONField(name = "name")
public String getName() {return name;}

@JSONField(name = "name")
public void setName(String name) {this.name = name;}

@JSONField(name = "AGE")
public String getAge() {return age;}

@JSONField(name = "AGE")
public void setAge(String age) {this.age = age;}
// FastJson在进行操作时,是根据getter和setter的方法进行的,并不是依据Field进行。

demo

public class PersonTest {
    private Person person;

    /**
    * 初始化对象
    */
    @Before
    public void setUp() {
        person = new Person();
        person.setName("gyl");
        person.setAge("20");
    }

    @Test
    public void test() {
        String jsonStr = JSONObject.toJSONString(person);
        System.out.println("bean to json:" + jsonStr);
        person = JSONObject.toJavaObject(JSONObject.parseObject(jsonStr), Person.class);
        System.out.println("json to bean:" + person.getName());
    }
}
///
Output:
bean to json:{"AGE":"20","name":"gyl"}
json to bean:gyl

JSONField默认支持的类型

public @interface JSONField {
    int ordinal() default 0;
    String name() default "";
    String format() default "";
    boolean serialize() default true;
    boolean deserialize() default true;
    SerializerFeature[] serialzeFeatures() default {};
    Feature[] parseFeatures() default {};
    String label() default "";
    boolean jsonDirect() default false;
    Class<?> serializeUsing() default Void.class;
    Class<?> deserializeUsing() default Void.class;
    String[] alternateNames() default {};
    boolean unwrapped() default false;
}

format规定日期格式

@JSONField(format="yyyy-MM-dd HH:mm:ss")
private Date date;

ordinal规定字段的顺序

@JSONField(ordinal = 3)
private int f0;
@JSONField(ordinal = 2)
private int f1;
@JSONField(ordinal = 1)
private int f2;
//fastjson序列化⼀个java bean,是根据fieldName的字母序进⾏序列的你可以通过ordinal指定字段的顺序。

serialize/deserialize指定字段不序列化

@JSONField(serialize=false)
public Date date;

@Scope

作用:
@Scope注解是springIoc容器中的一个作用域,在 Spring IoC 容器中具有以下几种作用域:
基本作用域singleton(单例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定义作用域
@Scope(“singleton”)

位置:

属性:
a.singleton单例模式 – 全局有且仅有一个实例
b.prototype原型模式 – 每次获取Bean的时候会有一个新的实例
c.request – request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效
d.session – session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效
e.globalsession – global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义

直接在bean对象方法上增加@Scope注解就可以如下:
@Scope注解默认的singleton实例,singleton实例的意思不管你使用多少次在springIOC容器中只会存在一个实例,演示如下只打印了一次创建实例:

细节:
几乎90%以上的业务使用singleton单实例就可以,所以spring默认的类型也是singleton,singleton虽然保证了全局是一个实例,对性能有所提高,但是如果实例中有非静态变量时,会导致线程安全问题,共享资源的竞争

当设置为prototype时:每次连接请求,都会生成一个bean实例,也会导致一个问题,当请求数越多,性能会降低,因为创建的实例,导致GC频繁,gc时长增加

Spring 只帮我们管理单例模式 Bean 的完整生命周期,对于 prototype 的 bean ,Spring 在创建好交给使用者之后则不会再管理后续的生命周期。

@PostConstruct & @PreDestroy

了解即可,详细:https://blog.csdn.net/tuesdayma/article/details/80532867

PostConstruct相当于init-method,使用在方法上,当Bean初始化时执行。
PreDestroy相当于destory-method,使用在方法上,当Bean销毁时执行。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
@Component
public class MyUtils {
 
    private static MyUtils taticInstance = new MyUtils();
 
    @Autowired
    private MyMethorClassService myService;
 
    @PostConstruct
    public void init(){
        staticInstance.myService = myService;
    }
    @PreDestroy
    public void destory(){
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值