Spring使用注解存储Bean对象

文章目录

  • 一. 配置扫描路径
  • 二. 使用注解储存Bean对象
    • 1. 使用五大类注解储存Bean
    • 2. 为什么要有五大类注解?
    • 3.4有关获取Bean参数的命名规则
  • 三. 使用方法注解储存Bean对象
    • 1. 方法注解储存对象的用法
    • 2. @Bean的重命名

在前一篇博客中( Spring项目创建与Bean的存储与读取(DL))介绍的是通过配置文件注册对象从而存储到 Spring 中,这种方式其实还是挺繁琐的。

实际上,在使用学习使用 Spring过程中,当我们要实现一个功能的时候,先应该考虑的是有没有相应的注解是实现对应功能的,Spring 中很多功能的配置都是可以依靠注解实现的,而本篇中介绍的是使用注解来存储 Bean 对象。

一. 配置扫描路径

首先还是要创建 Spring 项目,这里有问题还是去看我上一篇博客。当创建好项目后,我们的第一步就是配置扫描路径,这一步骤非常关键的,这里错了,之后的的操作就都不会生效了。

我们在resources目录下创建一个spring-config.xml配置文件,用来设置扫描的路径,在配置文件中添加如下内容:

<?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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
    <content:component-scan base-package=""></content:component-scan>
</beans>

其中<content:component-scan base-package=""></content:component-scan>里面 base-package的值设置为你需要扫描对象的根路径,这个路径从java目录开始,比如我在如图中的com.tr.demo目录下创建类:
img
那么这个配置文件中根路径就为com.tr.demo,所以我们将base-package的值设置为com.tr.demo

<content:component-scan base-package="com.tr.demo"></content:component-scan>

二. 使用注解储存Bean对象

想要使用注解,那得先知道能使用哪些注解,在 Spring 中有五大类注解和方法注解,分别为:

  1. 五大类注解:@Controller(控制器)、@Service(服务)、@Repository(仓库)、@Component(组件)、@Configuration(配置)。
  2. 方法注解:@Bean。

1. 使用五大类注解储存Bean

首先,我们来了解如何使用五大类注解来储存对象,先以@Controller注解为例,我们有如下的代码:

package com.tr.demo;

import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    public void sayHi() {
        System.out.println("Hi, UserController~");
    }
}

像这样在扫描路径下创建类,并在类上加上@Controller注解就将Bean存储到容器当中了。

接下来就要从 Spring 中读取出我们的对象,这里还是先使用依赖查找的方式来获取 Bean,使用五大类注解,默认情况下,Bean 的名字就是原类名首字母小写(小驼峰)。

import com.tr.demo.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class APP {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //获取对象时使用类名的小驼峰形式作为 name 参数
        UserController userController =  context.getBean("userController", UserController.class);
        userController.sayHi();
    }
}

运行结果:
img
要注意,是使用了五大类注解创建的类且类必须要在前面我们配置的扫描路径下(包括子包)才能将 Bean 存储到 Spring 当中,否则是无效的,所以这个扫描路径也叫做根路径。

设置根路径其实也是为了提高程序的性能,因为如果不设置根路径,Spring 就会扫描项目文件中所有的目录,但并不是所有类都需要储存到 Spring当中,这样性能就会比较低,设置了根路径,Spring 就只扫描该根路径下所有的目录就可以了,提高了程序的性能。

上面只使用了 @Controller,那么我们再来验证一下其他四个注解可不可以达到同样的目的,同时为了验证上面的结论,我们在com.tr.demo目录下再创建一个inner目录,在根路径外在创建一个类Student使用类注解。

img

package com.tr.demo.inner;
import org.springframework.stereotype.Component;

@Component
public class UserComponent {
    public void sayHi() {
        System.out.println("Hi, UserComponent~");
    }
}

package com.tr.demo.inner;
import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfiguration {
    public void sayHi() {
        System.out.println("Hi, UserConfiguration~");
    }
}

package com.tr.demo.inner;
import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {
    public void sayHi() {
        System.out.println("Hi, UserRepository~");
    }
}

package com.tr.demo.inner;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void sayHi() {
        System.out.println("Hi, UserService~");
    }
}

import com.tr.demo.UserController;
import com.tr.demo.inner.UserComponent;
import com.tr.demo.inner.UserConfiguration;
import com.tr.demo.inner.UserRepository;
import com.tr.demo.inner.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class APP {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //获取对象时使用类名的小驼峰形式作为 name 参数
        UserController userController =  context.getBean("userController", UserController.class);
        userController.sayHi();
        UserService service =  context.getBean("userService", UserService.class);
        service.sayHi();
        UserConfiguration configuration =  context.getBean("userConfiguration", UserConfiguration.class);
        configuration.sayHi();
        UserComponent component =  context.getBean("userComponent", UserComponent.class);
        component.sayHi();
        UserRepository repository =  context.getBean("userRepository", UserRepository.class);
        repository.sayHi();
    }
}

运行结果:

五大类注解效果都是一样的,而不在根路径下的Student是无效的。
img

还需要知道的是使用注解存储的 Bean 和使用XML存储的的 Bean 是可以一同使用的,比如我们将将刚刚有问题的Student重新通过XML的方式进行存储。

img

运行结果:

img

2. 为什么要有五大类注解?

既然都五大类完成的是同样的工作,那为什么要有五大类注解呢?

其实五大类注解主要是为了规范 Java 项目的代码,Java 项目的标准分层如下:

  1. 控制层(Controller)
  2. 服务层(Service)
  3. 数据持久层(Dao)

而五大类注解便是对应着不同的层级别使用的,让程序猿看到某一个注解就可以明确这个了类是做什么的。

  • @Controller:控制器,校验用户请求数据的正确性(安保系统);直接和前端打交道,校验前端发来请求是参数和合法性。

  • @Service:服务,编排和调度具体执行方法的(客服中心);不会直接操作数据库,根据请求判断具体调用哪个方法。

  • @Repository:数据持久层,直接和数据库交互(实际业务的执行),也叫DAO层(data access object)。

  • @Component:组件(工具类层),为整个项目存放一些需要使用的组件,但又和其他层没有什么实际交互。

  • @Configuration 配置项(项目中的一些配置)。

img

包括企业中也是按照这样的结构来将项目分层的,典型的比如阿里,它只是在标准分层在服务层(Service)做了一个扩展,划分的更加细致详细了。

img

五大类注解主要起到的是“见名知意”的作用,代码层面上来看,作用是类似的,我们去查看五大类类注解的源码看一看。

img

img

img

img

img
可以看到五大类的源码中除了 @Component 以外,其他四大类注解中都包含了 @Component 注解的功能,这四大类注解都是基于 @Component 实现的,是 @Component 拓展。

3.4有关获取Bean参数的命名规则

上文中在使用依赖查找的方式获取Bean时,getBean方法的BeanName是使用类名的小驼峰形式(即类名的首字母小写),这是因为使用注解储存对象时,默认会将类名的小驼峰形式设置为 Bean 的名字,但并不是完全依照这个规则的,是有特殊情况的。

比如,我们创建一个类,将它的前两个字母大写,如UConfig,此时来看使用类名的小驼峰形式还能不能获取到 Bean。

package com.tr.demo;

import org.springframework.stereotype.Repository;

@Repository
public class UConfig {
    public void sayHi(){
        System.out.println("Hi, UConfig~");
    }
}

启动类

import com.tr.demo.UConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class APP2 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        UConfig uConfig=  context.getBean("uConfig", UConfig.class);
        uConfig.sayHi();
    }
}

运行结果:
img
可以看到程序报错了,说没有找到beanNameuConfig的对象,那此时的beanName是什么呢?

此时再来试一下原本的类名(大驼峰),看能不能获取:

UConfig uConfig=  context.getBean("UConfig", UConfig.class);

运行结果:
img
此时就获取到了,好像多少有点玄学在里面,我们来翻一翻源码,看一看这是什么原因。

双击Shift进行全局搜索,上面是根于对象名称来找到对象的,所以我们输入beanName,试着搜索一下:

img

我们会发现有AnnotationBeanNameGenerator类与BeanNameGenerator接口,那我们就试着点到AnnotationBeanNameGenerator类源码看一看。

正常点开后看到的应该是 IDEA 将.class文件反编译出来的代码,缺少注释和明确的变量命名。

img

我们点击Download Sources将 Spring 源码下载下来即可,此时我们在在源码中就能看到下面的方法,看名字也知道,用来建立默认的BeanName的。

img

返回值是Introspector.decapitalize方法的返回值,再点进去看看这个方法。

img

此时我们就能分析得出结论,如果类名长度大于1并且满足第一个与第二个字母为大写,则构造的BeanName就为原类名,其他正常情况为类名的小驼峰形式,这就解释了UConfig类的BeanName为什么是原类名了。
而且我们会发现这个方法所在类是来自于jdk的。
img

所以,BeanName的规范命名规则并不是 Spring 独创的,而依照 Java 标准库的规则进行的。

  1. 如果类名不存在或类名为空字符串,BeanName为原类名。
  2. 如果类名字长度大于1,且第一个与第二个字符为大写,BeanName为原类名。
  3. 其他情况,BeanName为原类名的小驼峰形式。

三. 使用方法注解储存Bean对象

1. 方法注解储存对象的用法

五大类注解是添加到某个类上的,而方法注解是放到方法上的,当一个方法返回的是一个具体的实例对象时,我们就可以使用方法注解@Bean来将对象储存到 Spring,但是单单使用一个@Bean是不能够成功储存对象的,还需要在方法所在类上使用五大类注解才行,比如搭配一 个@Component 注解,方法注解是不能够单独使用的,@Bean注解必须要搭配五大类注解一起使用(Spring为了提升性能所做的规定,毕竟造方法的成本太低了,不能去扫描整个项目的方法吧)。

还是要注意使用必须是在根路径下。

比如我们有一个普通文章的实体类ArticleInfo

package com.tr.demo.model;

import java.time.LocalDateTime;

/**
 * 普通的文章实体类
 */
public class ArticleInfo {
    private int aid;
    private LocalDateTime createtime;
    private String title;
    private String author;
    private String content;
    
    public void setAid(int aid) {
        this.aid = aid;
    }
    public void setCreatetime(LocalDateTime createtime) {
        this.createtime = createtime;
    }
    public void setTitle(String title) {
        this.title = title;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "ArticleInfo{" +
                "aid=" + aid +
                ", createtime=" + createtime + "\n" +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' + "\n" +
                ", content='" + content + '\'' +
                '}';
    }
}

下面演示使用@Bean方法注解储存对象

package com.tr.demo;

import com.tr.demo.model.ArticleInfo;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
import java.time.LocalDateTime;

@Controller
public class Articles {
    @Bean// 将当前方法返回的对象存储到 IoC 容器
    public ArticleInfo getArt(){
        // 伪代码(实际上这里的 Bean 不是 new 出来的)
        ArticleInfo articleInfo = new ArticleInfo();
        articleInfo.setAid(1);
        articleInfo.setCreatetime(LocalDateTime.now());
        articleInfo.setTitle("夏日绝句");
        articleInfo.setAuthor("李清照");
        articleInfo.setContent("生当做人杰,死亦为鬼雄。至今思项羽,不肯过江东。");
        return articleInfo;
    }

    public void sayHi(){
        System.out.println("Hi, Articles~");
    }
}

获取方法注解储存的对象时,传入的BeanName参数值默认值就是方法名,我上面的代码中方法名为getArt,所以获取时,就使用getArt作为参数来进行获取。

import com.tr.demo.model.ArticleInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class APP3 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        ArticleInfo article =  context.getBean("getArt", ArticleInfo.class);

        System.out.println(article);
    }
}

运行结果:
img

2. @Bean的重命名

获取方法注解储存的对象时,传入的BeanName参数值默值为方法名,但像上面那样返回对象的方法名称往往是getXXX这样式取名的,虽然在语法与实现上是没有问题的,但实际开发写出这样的代码,看起来还是比较别扭的。

实际上注解 @Bean 是可以加参数的,给储存的对象起别名,像下面这个样子。

@Controller
public class Articles {
    @Bean("article")// 将当前方法返回的对象存储到 IoC 容器
    public ArticleInfo getArt(){
        // 伪代码(实际上这里的 Bean 不是 new 出来的)
        ArticleInfo articleInfo = new ArticleInfo();
        articleInfo.setAid(1);
        articleInfo.setCreatetime(LocalDateTime.now());
        articleInfo.setTitle("夏日绝句");
        articleInfo.setAuthor("李清照");
        articleInfo.setContent("生当做人杰,死亦为鬼雄。至今思项羽,不肯过江东。");
        return articleInfo;
    }

    public void sayHi(){
        System.out.println("Hi, Articles~");
    }
}

也可以给 Bean 设置多个别名,总结起来有如下几种方式:

//方式一(省略参数名的情况下默认是name)
@Bean("article1")
//方式二
@Bean(name = "article2")
//方式三
@Bean(value = "article3")
//起多个别名
@Bean(name = {"article4", "article5"})
@Bean(value = {"article6", "article7"})
@Bean({"article8", "article9", "article10"})

我们按照第 9 行的方式设置,此时获取方法注解储存的对象就能够使用别名来进行获取。

img

import com.tr.demo.model.ArticleInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class APP4 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        ArticleInfo article1 =  context.getBean("article6", ArticleInfo.class);
        System.out.println(article1);
        System.out.println("-----------------------------------------------------");
        ArticleInfo article2 =  context.getBean("article7", ArticleInfo.class);
        System.out.println(article2);
        System.out.println("-----------------------------------------------------");
    }
}

运行结果:
img

再想一下,当一个 Bean 有别名了,那使用之前那个方法名还能够获取到对象吗?尝试一下:

import com.tr.demo.model.ArticleInfo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class APP5 {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        ArticleInfo article =  context.getBean("getArt", ArticleInfo.class);
        System.out.println(article);
    }
}

运行结果:

此时就能发现是获取不到的
img
所以使用 @Bean 存储对象的beanName命名规则是,当没有设置name/value属性时,此时 Bean 的默认名字就是方法名,一旦添加了别名name/value属性后,就只能通过重命名的别名来获取 Bean 了,默认的使用方法名获取 Bean 对象就不能使用了。

还要简单注意一下,@Bean 使用时,同一类如果多个 Bean 使用相同的名称,此时程序执行是不会报错的,他会根据类加载顺序和类中代码从上至下的的顺序,将第一个 Bean 存放到 Spring 中,但第一个之后的对象就不会被存放到容器中了,也就是只有在第一次创建 Bean 的时候会将对象和 Bean 名称关联起来,后续再有相同名称的Bean存储时候,容器会自动忽略。

还可以通过类注解 @Order 注解控制类加载顺序(值越小,优先级越高),进而影响 Bean 的存放的先后顺序,这些也比较简单,就不做演示了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/42993.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

RS485/RS232自由转ETHERNET/IP网关rs485和232接口一样吗

你是否曾经遇到过这样的问题&#xff1a;如何将ETHERNET/IP网络和RS485/RS232总线连接起来呢&#xff1f; 远创智控的YC-EIP-RS485/232通讯网关&#xff0c;自主研发的ETHERNET/IP从站功能&#xff0c;完美解决了这个难题。这款网关不仅可以将ETHERNET/IP网络和RS485/RS232总线…

访客报警定位管理系统:提升安全管理水平的创新解决方案

在当前日益复杂的安全环境下&#xff0c;保障人员安全、提高安全响应能力和管理效率成为了各行各业的首要任务。 作为一种先进的安全管理解决方案&#xff0c;访客报警定位管理系统凭借其独特的优势和广泛的应用场景&#xff0c;正逐渐成为各行业安全管理的重要工具。 那么&a…

「深度学习之优化算法」(十七)灰狼算法

1. 灰狼算法简介 (以下描述,均不是学术用语,仅供大家快乐的阅读)   灰狼算法(Grey Wolf Algorithm)是受灰狼群体捕猎行为启发而提出的算法。算法提出于2013年,仍是一个较新的算法。目前为止(2020)与之相关的论文也比较多,但多为算法的应用,应该仍有研究和改进的余…

数学建模-时间序列分析 实例

实例1销量数据预测和实例2人口数据预测实例3上证指数预测和实例4gdp增长率预测 数据-定义时间 不加置信区间清晰点 例二 实例3

性能测试-Jmeter之Linux下压力测试

我们在做测试的时候&#xff0c;有时候要运行很久&#xff0c;公司用的测试服务器一般都是linux&#xff0c;就可以运行在linux下面&#xff0c;linux下面不能像windows一样有图形化界面&#xff0c;那怎么运行脚本呢&#xff0c;就先在windows上把脚本做好&#xff0c;然后在l…

云计算和云架构是什么 有什么用途?

云计算是一种基于互联网的计算方式&#xff0c;它通过网络将计算资源(如计算能力、存储、网络带宽等)以服务的形式提供给用户&#xff0c;并允许用户根据需求进行灵活的资源调配和管理。云计算通常分为三个层次&#xff0c;即基础设施即服务(IaaS)、平台即服务(PaaS)和软件即服…

Spring学习记录----十二、Spring IoC注解式开发

目录 十二、Spring IoC注解式开发 12.1 回顾注解 注解怎么定义&#xff0c;注解中的属性怎么定义&#xff1f; 注解怎么使用&#xff1f; 1--通过反射机制怎么读取注解&#xff1f; 代码 运行结果 2--通过反射机制怎么读取注解&#xff1f; 代码 运行结果 12.2 声明…

时序数据库 TDengine 与金山云两大产品完成兼容互认证

万物互联时代&#xff0c;企业数字化转型和政企上云如火如荼。在云计算迎来重大发展机遇的同时&#xff0c;数据库在企业数字化转型中也扮演着重要的角色——随着业务量的激增&#xff0c;数据库的弹性扩容、容灾备份等需求逐渐显现&#xff0c;在此挑战下&#xff0c;时序数据…

哈希:探索快速的数据存储和搜索方法

哈希&#xff1a;探索快速的数据存储和搜索方法 哈希表作为一种高效的数据存储结构&#xff0c;可以使数据的存储位置与关键码之间建立一一映射的关系&#xff0c;从而加快元素的搜索速度。然而&#xff0c;哈希方法也面临着哈希冲突的问题&#xff0c;即不同的关键字通过相同…

MyBatis操作数据库

1.MyBatis是什么&#xff1f; MyBatis 是⼀款优秀的持久层框架&#xff0c;它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了⼏乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接⼝和 Java POJO&#xf…

力扣 -- 918. 环形子数组的最大和

一、题目&#xff1a; 题目链接&#xff1a;918. 环形子数组的最大和 - 力扣&#xff08;LeetCode&#xff09; 二、解题步骤&#xff1a; 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码&#xff1…

Sevlet规范:HttpServlet类 和 HttpServletRequest接口 源码解析

1. HTTP协议解读 什么是协议&#xff1f; 协议实际上是某些人&#xff0c;或者某些组织提前制定好的一套规范&#xff0c;大家都按照这个规范来&#xff0c;这样可以做到沟通无障碍。协议就是一套规范&#xff0c;就是一套标准。由其他人或其他组织来负责制定的。我说的话你能…

辅助驾驶功能开发-功能规范篇(23)-2-Mobileye NOP功能规范

5.2 状态机要求 5.2.1 NOP/HWP 状态机 NOP/HWP状态机如下所示&#xff1a; 下表总结了这些状态&#xff1a; 状态描述Passive不满足功能条件&#xff0c;功能无法控制车辆执行器。Standby满足功能条件。该功能不是由驾驶员激活的。功能不控制车辆执行器。Active - Main功能由…

Mac 四大常用清理软件推荐,软件特色下载教程横向评测

Mac 一般来说基本是不会中毒的&#xff0c;而且像 现在的 windows 也是很少中毒&#xff0c;但我们可能还是需要一款杀毒清理软件&#xff0c;主要是为了清理垃圾&#xff0c;统一查看并管理软件开机自启、权限信息等&#xff0c;统一卸载清理等功能&#xff0c;另外我们可能还…

商城-学习整理-基础-分布式组件(三)

目录 一、前言二、Spring Cloud&Spring Cloud Alibaba1、Spring Cloud 与Spring Cloud Alibaba简介2、为什么使用Spring Cloud Alibaba3、版本选择4、项目中的依赖 三、Spring Cloud Alibaba-Nacos作为注册中心1、Nacos1&#xff09;、下载 nacos-server2&#xff09;、启动…

数据库运维——备份恢复

数据库备份&#xff0c;数据库为school&#xff0c;素材如下 1.创建student和score表 CREATE TABLE student ( id INT(10) NOT NULL UNIQUE PRIMARY KEY , name VARCHAR(20) NOT NULL , sex VARCHAR(4) , birth YEAR, department VARCHAR(20) , address VARCHAR(…

k8s部署高可用-redis

一、项目地址 ​GitHub - spotahome/redis-operator: Redis Operator creates/configures/manages high availability redis with sentinel automatic failover atop Kubernetes.​ 二、部署过程 一、部署operator控制器 1.把项目clone下来直接部署方便。 到这个目录下的这个…

华硕ROG幻14 2023 GA402X原装Windows11预装系统 工厂模式恢复安装带ASUSRecevory一键还原

华硕ROG幻14 2023 GA402X原装Windows11预装系统 工厂模式恢复安装带ASUSRecevory一键还原 安装还原方法 第一步&#xff1a;需要拥有文件格式为6个底包的文件第二步&#xff1a;创建系统u盘引导分区和存储 第三步&#xff1a;复制文件到u盘之后&#xff0c;启动华硕工厂模式…

Spring Security从入门到精通

Spring Security从入门到精通&#xff08;学习三更老师的视频&#xff09; 视频地址&#xff1a;我觉得讲的不赖。三更老师的Spring Security视频 课程介绍 0. 简介 ​ Spring Security 是 Spring 家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供…

数学建模的赛题类型

一、预测类 指通过分析已有的数据或者现象&#xff0c;找出其内在发展规律&#xff0c;然后对未来情形做出预测的过程。 根据已知条件和求解目的&#xff0c;往往将预测类问题分为&#xff1a;小样本内部预测&#xff0c;大样本内部预测。 解决预测类赛题的一般步骤&#xff…