@SpringBootApplication
- 标志主程序,主程序所在包及其所有子包下的组件都会被扫描进来
- 如要改变扫描路径:
- @SpringBootApplication(scanBasePackages=“com.atguigu”)
- @ComponentScan 指定扫描路径
- 此注释相当于下面三个注释的和:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan(“com.atguigu.boot”)
@Configuration
- 用在类上面表示这是一个配置类
- 配置类本身也是一个组件,代理Bean的方法
- 使用@Configuration(proxyBeanMethods = false):区分是否是单实例,默认单实例(true)
- Full(proxyBeanMethods = true)【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
- Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
-
- 类中使用@Bean标注在方法上给容器注册组件,默认也是单实例的
- 以方法名作为组件的id。返回类型就是组件类型。返回的值就是组件在容器中的实例
- 改变组件的id:@Bean(“tom”)—>此时组件的id就会tom
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
//3、从容器中获取组件
Pet tom01 = run.getBean("tom", Pet.class); //组件id,组件返回值类型
//MyConfig是一个配置类
MyConfig bean = run.getBean(MyConfig.class);
//获取类中注册的组件,和上面通过run获取的效果相同
User user = bean.user01();
@Component、@Controller、@Service、@Repository
@RestController
- Spring 4.0 版本开始添加进来的,主要用于更加方便的构建 RESTful Web 服务。
- 这是一个复合注解,
- @ReponseBody
- @RequestMapping
@RequestBody
- 前端需要使用POST进行提交
- 当前端将请求的内容放在请求体中的话需要使用该注解接收
json字符串中,如果value为""的话,后端对应属性如果是String类型的,那么接受到的就是"",如果是后端属性的类型是Integer、Double等类型,那么接收到的就是null。
:会直接接收成字符串
:会将json中的数据根据名称绑定
@Import
- 只能用在类上
- 可以用于导入第三方包 ,当然@Bean注解也可以,但是@Import注解快速导入的方式更加便捷
- 为了保证被扫描到一般和@Configuration配合使用
- @Import({User.class, DBHelper.class})
- 给容器中自动创建出这两个类型的组件、默认组件的名字就是全类名
- 第二种用法:importSelector方式
- 类要实现ImportSelector接口
- 接口方法返回值:可以返回空数组但是不能返回null,否则会报空指针异常
public class Myclass implements ImportSelector {
//返回值: 就是我们实际上要导入到容器中的组件全类名
//AnnotationMetadata表示当前被@Import注解给标注的所有注解信息
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
return new String[0];
//return new String[]{"com.yc.Test.TestDemo3"};
}
}
- 第三种用法:ImportBeanDefinitionRegistrar方式
- 类实现ImportBeanDefinitionRegistrar接口
- 相比较于第二种方式,可以为注册的bean指定id
public class Myclass2 implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
//指定bean定义信息(包括bean的类型、作用域...)
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestDemo4.class);
//注册一个bean指定bean名字(id)
beanDefinitionRegistry.registerBeanDefinition("TestDemo4444",rootBeanDefinition);
}
}
@Conditional
- 可以使用在类和方法上,类上只要不符合条件,该类全部组件都不创建。方法上只管当前方法
- @ConditionalOnBean(name = “组件id”):当组件容器中存在对应组件id时创建
- @ConditionalOnMissingBean:表示当容器中没有某个组件才进行组件注入
@ImportResource
- 原生配置文件引入
- @ImportResource(“classpath:beans.xml”) 应用在类上将原生配置文件中的组件注册进去
@ConfigurationProperties
- 比自带的 @Value更加方便
- 读取配置文件中的注解进行绑定
- SpringBoot项目兼容spring项目
- @ImportResource(locations = {“classpath:spring.xml”})
- 必须配合**@Component或者@EnableConfigurationProperties({类名.class})**使用
- @EnableConfigurationProperties({类名.class})可以在其他类上使用
- 方法一:
- @ConfigurationProperties(prefix = “aa”)使用在类上,prefix为前缀。匹配绑定
- 例如配置文件中的
aa.user=33
则33就可以和user属性进行绑定
//下面两个作用在实体类上自动绑定
@Component
@ConfigurationProperties(prefix = "config")
//
@EnableConfigurationProperties(xxx.class)
@ConfigurationProperties(prefix = "xxx")
@AutoConfigurationPackage
- 自动配置包
- 使用@import将AutoConfigurationPackages包下的Registrar类作为组件导入到容器中,然后使用Registrar中的方法批量完成组件的注册。
@Import(AutoConfigurationPackages.Registrar.class)
@Import(AutoConfigurationImportSelector.class)
- 可以理解为SpringBoot使用所有需要的给容器加载的所有配置类
- 虽然我们131个场景的所有自动配置启动的时候默认全部加载;但是最终还是会按需配置(@Conditional)
1、利用getAutoConfigurationEntry(annotationMetadata);给容器中批量导入一些组件
2、调用List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes)获取到所有需要导入到容器中的配置类
3、利用工厂加载 Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件
4、从META-INF/spring.factories位置来加载一个文件。
默认扫描我们当前系统里面所有META-INF/spring.factories位置的文件
spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有META-INF/spring.factories
@Conditional
- 下面的代码:
- 当容器中有MultipartResolver这个组件同时没有multipartResolver这个组件
- 就给容器中加上multipartResolver这个解析器,
- 实际上就是给MultipartResolver起了个别名以符合S平日那个MVC的命名要求
- @ConditionalOnMissingBean:底层使用这个注解保证了用户配置大于自动装配
@Bean
@ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件
@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件
public MultipartResolver multipartResolver(MultipartResolver resolver) {
//给@Bean标注的方法传入了对象参数,这个参数的值就会从容器中找。
//SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范
// Detect if the user has created a MultipartResolver but named it incorrectly
return resolver;
}
给容器中加入了文件上传解析器;
- 自动配置的原理
- 系统提供的应用程序启动器:
Lombok注解
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
- @No/AllArgsConstructor:无参构造/全参构造
- @Data:getter/setter方法
- @ToString:toString方法
- @EqualsAndHashCode:equals和hashcode方法
- @Slf4j:日志开发,可以使用 log.info()打印日志
@Order
- 决定Bean的执行顺序,从0开始,0位最先执行
- 不决定Bean的加载和实例化的顺序
- 在@Aspect中:
- 当有多个@Aspect时,在保持@Aspect执行原理的情况下再根据Order决定
around0--before0--around1--方法--arount1--around0
@MapperScan(“xx.xx.mapper”)
- 简化使用,其他接口都不用在使用@Mapper
@PathVariable
- 用来表示URL中的
/{xx}
占位符中的内容 - 当方法的参数名称和需要绑定的url中的变量一致的时候可以简写
("/{name}") @PathVariable String name
- 不一致
@PathVariable("name")
@RequestParam
- 相当于request.getParameter(“参数名”)
- value/name:请求参数中的名称(参数必写)
- required:请求参数中是否必须提供此参数,默认是true,(400错误)
- defaultValue:默认值
url?userName=zhl&userName=holley
:使用数组或者list@RequestParam(value="userName")String[] userNames
@RequestParam(value="list")List<String> list
@CookieValue和@RequestHeader
- 获取Cookie/请求头的数据,拥有的参数和RequestParam相同
JUnit5
@ModelAttribute
- 被该注释注释的方法,会在controller的每个方法执行前被执行
- 方法如果有返回值,会将返回值加入到ModelMap中
- value属性:指定key的名字,否则默认是返回值类型的首字母小写
- 与RequestMapping相同
- 可以通过入参接收前台提交的数据,而且对入参绑定的设置相同
- 入参绑定的数据如果没有设置可为空,不能接收空数据,否则会报错。
- 可以将数据放入Model中,对于一次请求Model是共享的。所以在处理方法中的Model里存放了该注解方法中存放的数据(也就是说一次请求的 Model是同一个)
- 具体使用方法 具体使用方法csdn
@JsonAlias
@Schedule
定时任务
@CrossOrigin
- 解决跨域问题
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
- 跨域也可以使用jsonp
@Secured
@EnableWebSecurity //启用Spring Security.
会拦截注解了@PreAuthrize注解的配置.
@EnableGlobalMethodSecurity(prePostEnabled=true)//有了这个下面的注解才能使用
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Secured({"ROLE_normal","ROLE_admin"})
- 拥有normal或者admin角色的用户都可以方法helloUser()方法。另外需要注意的是这里匹配的字符串需要添加前缀“ROLE_“。
- 但是对于同时拥有这两个权限就无能为力了
@PreAuthorize("hasAnyRole('normal','admin')")
- 有两个权限之一可以使用
@PreAuthorize("hasRole('normal') AND hasRole('admin')")
- 同时拥有两个权限可以使用
@PostAuthorize(" returnObject!=null && returnObject.username == authentication.name")
- 方法执行后再进行权限验证,适合验证带有返回值的权限,Spring EL 提供 返回对象能够在表达式语言中获取返回的对象returnObject。
- 方法执行后再进行权限验证,适合验证带有返回值的权限,Spring EL 提供 返回对象能够在表达式语言中获取返回的对象returnObject。
@Resource
- 这是Java自己的注解
- 自动注入,有两个属性值,name,type
- name:使用byName进行自动注入
- type:使用byType进行自动注入
@Resource(name = "redisTemplate")
private RedisTemplate<String, Object> redisTemplate;
//其中a是根据 @Service("a") 确定的,默认使用的就是类名
@Lazy
- 懒加载,被注解的Bean只有在被调用的是后才会实例化
- 没有拦截在时,默认Spring会在应用程序上下文的启动时创建所有单例bean
//和@Configuration一起使用在配置类上
//表示改配置类的所有@Bean都进行懒加载
@Configuration
@Lazy
public class AppConfig {
@Bean
public Country getCountry() {
return new Country();
}
}
//作用在特定的bean上
//只有被调用的时候才会被加载
@Bean
@Lazy
public Country getCountry() {
return new Country();
}
//只有在被调用的时候才会进行自动注入
@Lazy
@Autowired
private Country country;
@ResponseStatus
- 可以使用在类和方法上,但是一般都是使用在异常类和目标方法上
- value:可以使用HttpStatus枚举类中的属性。
- reason:自定义返回的错误信息
- 使用reason备注是的方法返回值就不会被处理了直接返回错误界面
//@RequestMapping或者@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.UNAUTHORIZED,reason = "no no no")
public Response unauthorized() {
return new Response(401, "Unauthorized", null);
}
//@ResponseStatus(value = A,reason = B) == response.sendError(A,B);
//@ResponseStatus(value = A) == response.sendStatus(A);
@RestControllerAdvice
注解@RestControllerAdvice用法途_restcontrolleradvice注解_oah1021的博客-CSDN博客
- basePackage:指定包的范围使用{}包裹,可以忽略不写,不写就默认作用所有的Controller
- @RestControllerAdvice(basePackages={“top.aa”});此时aa包下的所有Controller都被管理
- basePackageClasses/assignableTypes:与上面用法相同,指定作用的Controller类
- @RestControllerAdvice(basePackageClasses={TestController.class})
- annotations:指定一个或多个注解,被这些注解标记的Controller会被管理
- @ControllerAdvice(annotations = {TestAnnotation.class})
- 间接继承了@Component,所以该注解使用在类上
- 被该注解标记的类可以做控制器的一个全局配置没因为对所有的被@RequestMapping标记的控制器方法生效。
- 使用了该注解的类可以使用@ExceptionHandler、@InitBinder、@ModelAttribute注解到方法上,此时这些方法都会作用在所有被@RequestMapping注解的控制器方法上
- @ExceptionHandler:成为全局处理控制器中的异常
- @InitBinder:用来设置WebDataBinder,用于自动绑定前台请求参数到Model中。
- @ModelAttribute:本来作用是绑定键值对到Model中,当与@ControllerAdvice配合使用时,可以让全局的@RequestMapping都能获得在此处设置的键值对。
@ControllerAdvice
public class GlobalController{
//(1)全局数据绑定
//应用到所有@RequestMapping注解方法
//此处将键值对添加到全局,注解了@RequestMapping的方法都可以获得此键值对
@ModelAttribute
public void addUser(Model model) {
model.addAttribute("msg", "此处将键值对添加到全局,注解了@RequestMapping的方法都可以获得此键值对");
}
//(2)全局数据预处理
//应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
//用来设置WebDataBinder
@InitBinder("user")
public void initBinder(WebDataBinder binder) {
}
// (3)全局异常处理
//应用到所有@RequestMapping注解的方法,在其抛出Exception异常时执行
//定义全局异常处理,value属性可以过滤拦截指定异常,此处拦截所有的Exception类型的异常
@ExceptionHandler(Exception.class)
public String handleException(Exception e) {
return "error";
}
}
拓展:在事务管理中,如果我们自定义的异常继承的是Exception则事务无效,如果继承的是RunTimeException,则不会出现事务无效的问题。
@ModelAttribute
Spring注解@ModelAttribute - 哩个啷个波 - 博客园
- value/name:指定model中的属性的名称,也就是
- @ModelAttribute(“aa”) == Model.addAttribute(“aa”, xxx)
- 该注解可以使用发方法上、形参上、方法的返回值上。
- **方法上:**被标记的方法会此controller的每个方法执行前被执行
- 被注解的方法的返回值类型不同是会有区分
- **形参上:**说明该形参的值将从Model中获得,如果model中找不到,那么该参数会先被实例化,然后被添加到model中。在model中存在以后,请求中所有名称匹配的参数都会填充到该参数中。这在MVC中被称为是数据绑定,
- 返回值上:添加方法返回值到模型对象中,用于视图页面展示时使用。
//使用在void方法时,通过向入参处添加 Model 类型或 Map 类型的参数
//当注解void方法时,一般在方法的入参中使用Model参数,在方法体内用model.addAttribute(String name,Object object);将模型数据添加到模型对象中。
@ModelAttribute
public void NoneReturn(@RequestParam String data, Model model) {
model.addAttribute("指定一个名称",data);
}
//也有一种不用addAttribute方法的方式,这种方式不推荐,会在model中形成一个key为void,值为null 的数据,解决出现key为void,值为null的方法是,在注释上添加name/value
@ModelAttribute
public void getStudent(@RequestParam(value = "id", required = false) String idStr, Map<String, Object> map) {
Integer id = Integer.parseInt(idStr);
System.out.println("student id: " + id);
map.put("student", new Student(1, "lisi", 23));
}
//当注解返回具体类型的方法时,我们一般用@ModelAttribute的value属性指定model属性的名称。model属性对应的对象就是方法的返回值。
@ModelAttribute("指定一个名称")
@ModelAttribute//如果这样使用,不指定名称,则model属性名就会默认是返回类型的首字母小写
public String ReturnRealClass(@RequestParam String data) {
return data;
}
???????????????
③当@ModdelAttribute和@RequestMapping共同注解一个方法时。
@RequestMapping(value = "指定一个访问路径")
@ModelAttribute("指定一个名称")
public String Fix() {
return "猛虎蔷薇";
}
这时就比较特殊了,此时方法的返回值并不是表示一个视图名称,而是model属性的值,此时的视图名称就是@RequestMapping中指定的访问路径的最后一层去掉扩展名。
这样说可能比较抽象,举个例子:
假设@RequestMapping("/MainPage.txt"),此时的视图名称就会被解析为MainPage,当然了具体处理的时候前后还会加上配置的suffix和prefix.
@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) { }
//这个pet可能从何而来?
//首先会在 implicitModel(SpringMVC运行流程中的一个组件)中查找 key 对应的对象。
//它可能因为@SessionAttributes标注的使用已经存在于model中
//它可能因为在同个控制器中使用了@ModelAttribute方法已经存在于model中
//它可能是由URI模板变量和类型转换中取得的
//它可能是调用了自身的默认构造器被实例化出来的
//下面的例子中,model属性的名称("account")与URI模板变量的名称相匹配。如果配置了一个可以将String类型的账户值转换成Account类型实例的转换器Converter<String, Account>,那么上面这段代码就可以工作的很好,而不需要再额外写一个@ModelAttribute方法。(使用WebDataBinder)
@RequestMapping(path = "/accounts/{account}", method = RequestMethod.PUT)
public String save(@ModelAttribute("account") Account account) {}
//进行了数据绑定后,则可能会出现一些错误,比如没有提供必须的字段、类型转换过程的错误等。若想检查这些错误,可以在标注了@ModelAttribute的参数紧跟着声明一个BindingResult参数:
@RequestMapping(path = "/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) {
new PetValidator().validate(pet, result);//这里是自己定制的验证器 ???什么是定制验证器
if (result.hasErrors()) {
return "petForm";
}
}
//除了系上面的方法也可以使用在@Valid标注,这样验证器机会被自动调用
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result)
https://blog.csdn.net/daobuxinzi/article/details/126416658
@RequestMapping(value = "指定路径")
public @ModelAttribute("user") User helloWorld(User user) {
return new User();
}
//此时会添加返回值到模型数据中供视图展示使用。
@SessionAttributes
SpringMVC中的@SessionAttributes注解【详解】_你好像很好吃a的博客-CSDN博客
- value:通过属性名制定需要放到会话中的属性。
- types:通过模型属性的对象类型指定哪些模型属性需要放到会话中。
- 配合使用:@SessionAttributes(types = {User.class, String.class}, value={“user1”, “user2”}
- 该注解可以将ModelMap、Model、Session、Map、Request中的值转储到Session中。
- 注解只能使用在类上,用于多个请求之间的参数传递。
- SessionStatus.setComplete:清除通过该注解放入session中的参数,session原来有的不会被清除
- @SessionAttributes设置的参数只用于暂时的传递(存入sessionAttributeStore),而不是长期的保存,长期保存的数据还是要放到Session中。(也方便后续的分开清除(通过:status.setComplete()))
- 作用:ModelMap中的属性作用域是request级别时,也就是说,当本次请求结束后,ModelMap中的属性将销毁。如果希望在多个请求中共享ModelMap中的属性,必须将其属性转存到session中,这样ModelMap的属性才会被跨请求访问,此时就可以使用该注解。
@Controller
@SessionAttributes("user") //将ModelMap中key为user的属性共享到session中
public class DemoController {
@RequestMapping("/hello")
public String hello(ModelMap model) {
//向ModelMap中添加key为user和user1的属性
model.addAttribute("user", new User(520, "U love me"));//此时user就被共享到了session中
model.addAttribute("user1", new User("I love U"));
return "result";
}
}
//会将User类型的所有属性值存入到Session中,下面例子中的user1、user2user3都会存到session中
@SessionAttributes(types = {User.class})
@Controller
public class DemoController{
@RequestMapping("/hello")
public String hello(Map<String, Object> map){
map.put("user1", new User(520, "U love me"));
map.put("user2", new User(520, "U love me"));
map.put("user3", new User(520, "U love me"));
return "hello";
}
}
//此时知识清楚了通过该注解放入session中的参数,不会清除应用session中的参数
@Controller
@SessionAttributes("pet")
public class EditPetForm {
// ...
@PostMapping("/pets/{id}")
public String handle(Pet pet, BindingResult errors, SessionStatus status){
if (errors.hasErrors) {
// ...
status.setComplete(); //调用SessionStatus.setComplete来清除
// ...
}
}
}
- 拓展:在Spring MVC中,Request、Response、Session、InputStream、OutputStream这些对象是自动注入的。也就是在形参中可以直接接收。