spring5注解
1spring5注解
1.1 注解导入
1.使用注解时必须要有aop依赖
1.1需要在xml文件中导入context依赖
引入xsi:schemaLocation属性
xmlns:是XML NameSpace的缩写,因为XML文件的标签名称都是自定义的,自己写的和其他人定义的标签很有可能会重复命名,而功能却不一样,所以需要加上一个namespace来区分这个xml文件和其他的xml文件,类似于java中的package。
xsi:schemaLocation用于声明了目标名称空间的模式文档。
? xsi:schemaLocation:1.用于声明了目标名称空间的模式文档
? 2.属性的值由一个URI引用对组成,两个URI之间以空白符分隔。第一个URI是名称空间的名字,第二个URI给出模式文档的位置,模式处理器将从这个位置读取模式文档,该模式文档的目标名称空间必须与第一个URI相匹配
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
2.添加注解的支持
<!-- 注解的支持-->
<context:annotation-config/>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
1.2 注解解释
1@Autowired
-
直接在属性上使用即可
-
使用Autowired就不用写set方法了,前提是自动装配的属性要在IOC容器上存在,且符合名字byname
package com.wxy.pojo; import org.springframework.beans.factory.annotation.Autowired; public class People { @Autowired private Dog dog; @Autowired private Cat cat; private String name; public Dog getDog() { return dog; } // public void setDog(Dog dog) { // this.dog = dog; // } public Cat getCat() { return cat; } // public void setCat(Cat cat) { // this.cat = cat; // } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "People{" + "dog=" + dog + ", cat=" + cat + ", name=‘" + name + ‘\‘‘ + ‘}‘; } }
3.@Autowired(required = false):required = false说明对象可以为空
public class People { @Autowired private Dog dog; @Autowired(required = false) private Cat cat; private String name;
4.@Qualifier(value = "cat11")
如果xml中一个类对应多个bean时,即自动装配一个注解@Autowired无法完成时,可以使用@Qualifier配合使用
<bean id="dog" class="com.wxy.pojo.Dog"/>
<bean id="cat" class="com.wxy.pojo.Cat"/>
<bean id="cat11" class="com.wxy.pojo.Cat"/>
public class People {
@Autowired
private Dog dog;
@Autowired
@Qualifier(value = "cat11")
private Cat cat;
private String name;
}
5.@Resource (java注解)
@Autowired
private Dog dog;
@Resource(name="cat")
// @Resource(name="cat11")
// @Qualifier(name = "cat11")
private Cat cat;
private String name;
6.@Nullable指定字段可以为空
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
7.小结
@Resource 和@Autowired的区别
-
都是用来自动装配的,可以放在属性字段上
-
@Autowired通过byType方式实现,【常用】要求对象必须存在。@Qualifier通过byName方式实现。
-
@Resource默认通过byName方式实现,如果找不到就通过byType方式寻找,如果两种都找不到,便报错。
-
执行顺序不同:
-
@Autowired通过byType方式实现
-
@Resource默认通过byName方式实现
1.3 spring注解
需要添加注解扫描的包
<!-- 指定扫描的包,在下面的注解就会生效-->
<context:component-scan base-package="com.wxy"/>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 指定扫描的包,在下面的注解就会生效-->
<context:component-scan base-package="com.wxy"/>
<context:annotation-config/>
<bean id="user" class="com.wxy.pojo.User">
</bean>
</beans>
1.3.1 @Component
import org.springframework.stereotype.Component;
//@Component等价于<bean id="user" class="com.wxy.pojo.User"/>
@Component
public class User {
public String name = "wxy";
}
1.3.2 @Value
@Component
public class User {
// @Value()相当于<property name="name" value="wxy"/>
@Value("wxy")
public String name;
}
@Component
public class User {
// 可以放在set上方
public String name;
@Value("wxy")
public void setName(String name) {
this.name = name;
}
}
1.3.3 衍生注解
@Repository
@Service
@Controller
@Component有几个衍生注解,在web开发过程中,会分为mvc三层
-
dao:【@Repository】
-
service:【@Service】
-
controller:【@Controller】
这四个注解功能都是一样的,都是将某个类装载到spring中。
1.3.4 @Scope注解是什么
@Scope注解是springIoc容器中的一个作用域,在 Spring IoC 容器中具有以下几种作用域:基本作用域singleton(单例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定义作用域
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应用中才有意义
@Component
@Scope("singleton")
public class User {
// @Value()相当于<property name="name" value="wxy"/>
public String name;
@Value("wxy")
public void setName(String name) {
this.name = name;
}
}
1.3.5 用java方式实现程序
所用注解
@Configuration
@ComponentScan
@Import
@Bean
//是spring容器托管,注册到容器中,因为他本来就是@Component.@Configuration代表是一个配置类,就是beans.xml
@Configuration
//相当于<context:component-scan base-package="com.wxy"/>
@ComponentScan("com.wxy.pojo")
//同时开发时也可引入另一个人的配置
@Import(UserConfig2.class)
public class UserConfig {
//相当于<bean id="getUser" class="com.wxy.pojo.User"/>
@Bean
public User getUser(){
return new User();
}
//测试文件
public class MyTest {
public static void main(String[] args) {
//如果完全使用配置类方式去做,我们只能通过AnnotationConfig获取上下文来获取容器,通过配置类的class来加载
ApplicationContext config = new AnnotationConfigApplicationContext(UserConfig.class);
User getUser = config.getBean("getUser", User.class);
System.out.println(getUser.getName());
}
}
错误:java: Internal compiler error: java.util.ServiceConfigurationError: javax.annotation.processing.Processor: Provider lombok.launch.AnnotationProcessorHider$ClaimingProcessor not found at java.util.ServiceLoader.fail(ServiceLoader.java:239)
lombok问题如何解决
类级别和方法级别处理是什么
1.3.6注解
@RequestMapping
<!-- spring中一般采用@RequestMapping注解来完成映射关系
要想是@RequestMapping生效,要在上下文中注册控制器所必须的
DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter实例
这两个方法分别在类级别和方法级别处理
annotation-driven配置帮助我们完成了上面两个实例的加载
-->
<mvc:annotation-driven/>
@Controller
@RequestMapping(path = "/user")
public class UserController {
// 该方法将接收 /user/login 发来的请求[重点]
//带有 username=username&password=123456 的请求参数
@RequestMapping(path = "/login", params={"username=username","password=123456"})
public String login() {
return "success";
}
}
@Controller
public class UserController {
// 该方法将接收 /user/login 发来的请求[重点]
//带有 username=username&password=123456 的请求参数
@RequestMapping(path = "/user/login", params={"username=username","password=123456"})
public String login() {
return "success";
}
}
@PathVariable
在Spring MVC中可以使用 @PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量上。
//RestFul风格:url为:http://localhost:8080/SpringMVC_04_controller_war_exploded/hello/1/1
@RequestMapping("/hello/{a}/{b}")
public String hello(@PathVariable int a,@PathVariable int b, Model model){
int c=a+b;
model.addAttribute("msg","结果为"+c);
return "hello";
}
//原始风格:url为:http://localhost:8080/SpringMVC_04_controller_war_exploded/hello1?a=1&b=2
@RequestMapping("/hello1")
public String hello2(int a,int b, Model model){
int c=a+b;
model.addAttribute("msg","结果为"+c);
return "hello";
}
传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get
? http://127.0.0.1/item/queryItem.action?id=1 查询,GET
? http://127.0.0.1/item/saveItem.action 新增,POST
? http://127.0.0.1/item/updateItem.action 更新,POST
? http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST
使用RESTful操作资源 :可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能可以不同!
? http://127.0.0.1/item/1 查询,GET
? http://127.0.0.1/item 新增,POST
? http://127.0.0.1/item 更新,PUT
? http://127.0.0.1/item/1 删除,DELETE
@RequestBody
? 主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的);GET方式无请求体,所以使用@RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
@RequestParam
//http://localhost:8080/SpringMVC_04_controller_war_exploded/hello1?inta=1&b=2
@RequestMapping("/hello1")
//这个注解可以改变传参的变量
public String hello2(@RequestParam("inta") int a, int b, Model model){
int c=a+b;
model.addAttribute("msg","结果为"+c);
return "hello";
}
@RequestParam 支持下面四种参数
defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值
name 绑定本次参数的名称,要跟URL上面的一样
required 这个参数是不是必须的
value 跟name一样的作用,是name属性的一个别名
过滤器
SpringMVC提供的乱码过滤器
<!--SpringMVC提供的乱码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
@ResponseBody
不走视图解析器,直接返回json字符串
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!-- 前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀-->
<property name="suffix" value=".jsp"/>
</bean>
@RestController
? @RestController注解,相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
@CrossOrigin
前后端分离时处理跨域注解,放在controller中
@CrossOrigin//放在类上,整个类就跨域了
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService;
@CrossOrigin//放在方法上方法就跨域了
@RequestMapping("/allBook")
// @GetMapping("/allBook")
public String list(Model model) {
List<Books> list = bookService.queryAllBook();
model.addAttribute("list", list);
return "allBook";
}
}
全局配置类-配置跨域请求
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
//全局配置类-配置跨域请求
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
/*
* 1.访问路径
* 2.请求来源
* 3.方法
* 4.允许携带
* 5.最大时间
* */
registry.addMapping("/**")
.allowedOrigins("http://localhost:8080","null")
.allowCredentials(true)
.allowedMethods("GET","POST","PUT","OPTIONS","DELETE")
.maxAge(3600);
}
}
@Configuration
放在类上说明是一个全局控制类。
@Configuration注解的配置类有如下要求:
- @Configuration不可以是final类型;
- @Configuration不可以是匿名类;
- 嵌套的configuration必须是静态类。
@Override
是伪代码,表示重写。
一般用途
- 帮助自己检查是否正确的复写了父类中已有的方法
- 告诉读代码的人,这是一个复写的方法