`
ioio
  • 浏览: 142473 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Spring Security 尝试

阅读更多

1.配置文件

首先,在web.xml文件中添加FilterToBeanProxy过滤器配置:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 <filter>   
 2       <filter-name>springSecurityFilterChain</filter-name>
 3      <filter-class>
 4         org.springframework.security.util.FilterToBeanProxy
 5      </filter-class>
 6      <init-param>       
 7           <
param-name>targetClass</param-name>
 8          <param-value>           
 9               org.springframework.security.util.FilterChainProxy
10          </param-value>
11      </init-param>
12 </filter>
13

 

org.springframework.security.util.FilterToBeanProxy实现了Filter接口,它通过调用 WebapplicationContextUtils类的getWebApplicationnContext(servletContext)方法来获取Spring的应用上下文句柄,并通过getBean(beanName)方法来获取Spring受管Bean的对象,即这里targetClass 参数配置的Bean,并通过调用FilterChain Proxy的init()方法来启动Spring Security过滤器链进行各种身份验证和授权服务(FilterChainProxy类也是实现了Filter接口),从而将过滤功能委托给 Spring的FilterChainProxy受管Bean(它维护着一个处理验证和授权的过滤器列表,列表中的过滤器按照一定的顺序执行并完成认证过程),这样即简化了web.xml文件的配置,又能充分利用 Spring的IoC功能来完成这些过滤器执行所需要的其它资源的注入。

    当用户发出请求,过滤器需要根据web.xml配置的请求映射地址来拦截用户请求,这时Spring Security开始工作,它会验证你的身份以及当前请求的资源是否与你拥有的权限相符,从而达到保护Web资源的功能,下面是本例所要过滤的用户请求地址:

 1 <filter-mapping>
 2 
 3        <filter-name>springSecurityFilterChain</filter-name>
 4 
 5        <url-pattern>/j_spring_security_check</url-pattern>
 6 
 7     </filter-mapping>
 8 
 9     <filter-mapping>
10 
11        <filter-name>springSecurityFilterChain</filter-name>
12 
13        <url-pattern>/*</url-pattern>
14 
15 </filter-mapping>

 

注意: j_spring_security_check是Spring Security默认的进行表单验证的过滤地址,你也可以修改为别的名称,但是需要和
applicationContext-security.xml中相对应,当然还会涉及到其它一些默认值(可能是一个成员变量,也可能是别的请
求地址)

2 配置applicationContext-security.xml

2.1 FilterChainProxy过滤器链

    FilterChainProxy会按顺序来调用一组filter,使这些filter即能完成验证授权的本质工作,又能享用Spring Ioc的功能来方便的得到其它依赖的资源。FilterChainProxy配置如下:

<!--<br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 <bean id="filterChainProxy"   
        class
="org.springframework.security.util.FilterChainProxy">
 2      <property name="filterInvocationDefinitionSource">
 3         <value><![CDATA[         
                CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 
 4              PATTERN_TYPE_APACHE_ANT         
                /**=httpSessionContextIntegrationFilter,logoutFilter,
 5              authenticationProcessingFilter,securityContextHolderAwareRequestFilter,
 6              rememberMeProcessingFilter,anonymousProcessingFilter,exceptionTranslationFilter,
 7              filterSecurityInterceptor 
 8         ]]></value>
 9      </property>
10 </bean>

    CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON 定义URL在匹配之前必须先转为小写,PATTERN_TYPE_APACHE_ANT 定义了使用Apache ant的匹配模式,/**定义的将等号后面的过滤器应用在那些URL上,这里使用全部URL过滤,每个过滤器之间都适用逗号分隔,它们按照一定的顺序排列。

注意:
特别需要注意的是,即使你配置了系统提供的所有过滤器,这个过滤器链会很长,但是千万不要使用换行,否则它们不会正常工作,容器甚至不能正常启动。

下面根据FilterChainProxy的配置来介绍各个过滤器的配置,各个过滤器的执行顺序如以上配置。

    首先是通道处理过滤器,如果你需要使用HTTPS,这里我们就使用HTTP进行传输,所以不需要配置通道处理过滤器,然后是集成过滤器,配置如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 <bean id="httpSessionContextIntegrationFilter"
2 
3 class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>

    httpSessionContextIntegrationFilter是集成过滤器的一个实现,在用户的一个请求过程中,用户的认证信息通过 SecurityContextHolder(使用ThreadLoacl实现)进行传递的,所有的过滤器都是通过 SecurityContextHolder来获取用户的认证信息,从而在一次请求中所有过滤器都能共享Authentication(认证),减少了 HttpRequest参数的传送,下面的代码是从安全上下文的获取Authentication对象的方法:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 SecurityContext context = SecurityContextHolder.getContext();
2 
3 Authentication authentication = context.getAuthentication();

    但是,ThreadLoacl不能跨越多个请求存在,所以,集成过滤器在请求开始时从Http会话中取出用户认证信息并创建一个 SecurityContextHolder将Authentication对象保存在其中,在请求结束之后,在从 SecurityContextHolder中获取Authentication对象并将其放回Http会话中,共下次请求使用,从而达到了跨越多个请求的目的。集成过滤器还有其它的实现,可以参考相关文档。

注意:集成过滤器必须在其它过滤器之前被使用。

logoutFilter(退出过滤器) ,退出登录操作:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 <bean id="logoutFilter"
 2 
 3     class="org.springframework.security.ui.logout.LogoutFilter">
 4 
 5     <constructor-arg value="/index.jsp"/>
 6 
 7     <constructor-arg>
 8 
 9        <list>
10 
11            <!-- 实现了LogoutHandler接口(logout方法) -->
12 
13            <ref bean="rememberMeServices"/>
14 
15            <bean class="org.springframework.security.ui.logout.SecurityContextLogoutHandler"/>
16 
17        </list>
18 
19     </constructor-arg>
20 
21 </bean>

a LogoutFilter的构造函数需要两个参数,第一个是退出系统后系统跳转到的URL,第二个是一个LogoutHandler类型的数组,这个数组里的对象都实现了LogoutHandler接口,并实现了它的logout方法,用户在发送退出请求后,会一次执行LogoutHandler数组的对象并调用它们的 logout方法进行一些后续的清理操作,主要是从SecurityContextHolder对象中清楚所有用户的认证信息(Authentication对象),将用户的会话对象设为无效,这些都时由SecurityContextLogoutHandler来完成。 LogoutFilter还会清除Cookie记录,它由另外一个Bean来完成(RememberMeServices)。

    <ref bean="rememberMeServices"/>标记指向了我们另外配置的一个Bean:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 <bean id="rememberMeServices"    
        class
="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices"
2     p:key="springsecurity"
3     p:userDetailsService-ref="userDetailsService"/>

    TokenBasedRememberMeServices继承自系统的AbstractRememberMeServices抽象类(实现了 RememberMeServices和 LogoutHandler两个接口), RememberMeServices接口的loginSuccess方法负责在用户成功登录之后将用户的认证信息存入Cookie中,这个类在后续的过滤器执行过程中也会被用到。

  过滤器链的下个配置的过滤器是authenticationProcessingFilter(认证过程过滤器),我们使用它来处理表单认证,当接受到与filterProcessesUrl所定义相同的请求时它开始工作:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 <bean id="authenticationProcessingFilter"
 2 
 3     class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter"
 4 
 5     p:authenticationManager-ref="authenticationManager"
 6     p:authenticationFailureUrl="/login.jsp?login_error=1"
 7     p:defaultTargetUrl="/default.jsp"
 8     p:filterProcessesUrl="/j_spring_security_check"
 9     p:rememberMeServices-ref="rememberMeServices"/>

    下面列出了认证过程过滤器配置中各个属性的功能:

    1.authenticationManager     认证管理器

    2.authenticationFailureUrl 定义登录失败时转向的页面

    3.defaultTargetUrl         定义登录成功时转向的页面

    4.filterProcessesUrl        定义登录请求的地址(在web.xml中配置过)

    5.rememberMeServices        在验证成功后添加cookie信息

    这里也用到了rememberMeServices,如果用户认证成功,将调用RememberMeServices的loginSuccess方法将用户认证信息写入Cookie中,这里也可以看到使用IoC的好处。

定用户是否有权限访问受保护资源的第一步就是要确定用户的身份,最常用的方式就是用户提供一个用户名和密码以确认用户的身份是否合法,这一步就是由认证过程过滤器调用authenticationManager(认证管理器)来完成的。 org.springframework.security.AuthenticationManager接口定义了一个authenticate方法,它使用Authentication作为入口参数(只包含用户名和密码),并在验证成功后返回一个完整的Authentication对象(包含用户的权限信息GrantedAuthority数组对象),authenticationProcessingFilter(认证过程过滤器)会将这个完整的 Authentication对象存入SecurityContext中,如果认证失败会抛出一个AuthenticationException并跳转到authenticationFailureUrl 定义的URL.认证管理其配置如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> --> 1 <bean id="authenticationManager"
 2 
 3 class="org.springframework.security.providers.ProviderManager"
 4  p:sessionController-ref="concurrentSessionController">
 5     <property name="providers">
 6        <list>
 7            <ref bean="daoAuthenticationProvider"/>
 8            <bean
 9 
10 class="org.springframework.security.providers.anonymous.AnonymousAuthenticationProvider"
11               p:key="springsecurity"/>
12            <bean
13 
14 class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider"
15               p:key="springsecurity"/>
16        </list>
17     </property>  
18 </bean>

    正如在配置中看到的一样,系统使用org.springframework.security.providers.ProviderManager(提供者管理器)类作为认证管理器的一个实现,事实上这个类是继承自实现了AuthenticationManager接口的 AbstractAuthenticationManager类。需要注意的是ProviderManager(提供者管理器)自己并不实现身份验证,而是把这项工作交给了多个认证提供者(提供者集合)或者说的多个认证来源。

注意:Spring Security为我们提供的所有认证提供者实现都是org.springframework.security.providers .AuthenticationProvider
接口的实现类,它们都实现了此接口的authenticate方法,如果你正在看源代码,会发现这个authenticate方法事实上和Authe
nticationManager(认证管理器)接口的authenticate方法完全一样。

 

------------------------各种认证方式--------------------------------------

     

            

DaoAuthenticationProvider

从数据库中读取用户信息验证身份

AnonymousAuthenticationProvider

匿名用户身份认证

RememberMeAuthenticationProvider

已存cookie中的用户信息身份认证

AuthByAdapterProvider

使用容器的适配器验证身份

CasAuthenticationProvider

根据Yale中心认证服务验证身份, 用于实现单点登陆

JaasAuthenticationProvider

JASS登陆配置中获取用户信息验证身份

RemoteAuthenticationProvider

根据远程服务验证用户身份

RunAsImplAuthenticationProvider

对身份已被管理器替换的用户进行验证

X509AuthenticationProvider

X509认证中获取用户信息验证身份

TestingAuthenticationProvider

单元测试时使用

 

 

---------------------end-------------------------------------------------------

从上面的表中可以看出,系统为我们提供了不同的认证提供者,每个认证提供者会对自己指定的证明信息进行认证,如DaoAuthenticationProvider仅对UsernamePasswordAuthenticationToken这个证明信息进行认证。

    在实际项目中,用户的身份和权限信息可能存储在不同的安全系统中(如数据库,LDAP服务器,CA中心)。

    作为程序员,我们可以根据需要选择不同的AuthenticationProvider(认证提供者)来对自己的系统提供认证服务。

    这里我们着重介绍DaoAuthenticationProvider,它从数据库中读取用户信息验证身份,配置如下:

 

 <bean id="daoAuthenticationProvider" 
        class
="org.springframework.security.providers.dao.DaoAuthenticationProvider"
2     p:passwordEncoder-ref="passwordEncoder"
3     p:userDetailsService-ref="userDetailsService"/>
4 <bean id="passwordEncoder"
5     class="org.springframework.security.providers.encoding.Md5PasswordEncoder"/>

还记得前面配置的RememberMeServices吗?它也有一个和DaoAuthenticationProvider同样的属性 userDetailsService,这是系统提供的一个接口(org.springframework.security.userdetails.UserDetailsService),在这里我们把它单独提出来进行介绍。

    首先我们需要了解Spring Security为我们提供的另外一个重要的组件,org.springframework.security.userdetails .UserDetails接口,它代表一个应用系统的用户,该接口定义与用户安全信息相关的方法:

    String getUsername():获取用户名;

    String getPassword():获取密码;

    boolean isAccountNonExpired():用户帐号是否过期;

    boolean isAccountNonLocked():用户帐号是否锁定;

    boolean isCredentialsNonExpired():用户的凭证是否过期;

    boolean isEnabled():用户是否处于激活状态。

    当以上任何一个判断用户状态的方法都返回false时,用户凭证就被视为无效。UserDetails接口还定义了获取用户权限信息的 getAuthorities()方法,该方法返回一个GrantedAuthority[]数组对象,GrantedAuthority是用户权限信息对象,这个对象中定义了一个获取用户权限描述信息的getAuthority()方法。

    UserDetails即可从数据库中返回,也可以从其它如LDAP中返回,这取决与你的系统中使用什么来存储用户信息和权限以及相应的认证提供者。这里我们只重点介绍DaoAuthenticationProvider(从数据库中获取用户认证信息的提供者),本人水平有限,在项目中还没有机会用到其它提供者。说到这里,这个封装了用户详细信息的UserDetails该从哪儿获取呢?这就是我们接下来要介绍的UserDetailsService接口,这个接口中只定义了唯一的UserDetails loadUserByUsername(String username)方法,它通过用户名来获取整个UserDetails对象。

    看到这里你可能会有些糊涂,因为前面提到的Authentication对象中也存放了用户的认证信息,需要注意Authentication对象才是 Spring Security使用的进行安全访问控制用户信息安全对象。实际上,Authentication对象有未认证和已认证两种状态,在作为参数传入认证管理器(AuthenticationManager)的authenticate方法时,是一个未认证的对象,它从客户端获取用户的身份信息(如用户名,密码),可以是从一个登录页面,也可以从Cookie中获取,并由系统自动构造成一个Authentication对象。而这里提到的 UserDetails代表一个用户安全信息的源(从数据库,LDAP服务器,CA 中心返回),Spring Security要做的就是将这个未认证的Authentication对象和UserDetails进行匹配,成功后将UserDetails中的用户权限信息拷贝到Authentication中组成一个完整的Authentication对象,共其它组件共享。

    这样,我们就可以在系统中获取用户的相关信息了,需要使用到Authentication对象定义的Object getPrincipal()方法,这个方法返回一个Object类型的对象,通常可以将它转换为UserDetails,从而可以获取用户名,密码以及权限等信息。代码如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 UserDetails details = (UserDetails)authentication.getPrincipal();
2 
3 GrantedAuthority[] authority = details.getAuthorities();

    前面介绍了DaoAuthenticationProvider,它可以从数据库中读取用户信息,同样也可以从一个用户属性文件中读取,下一篇文章中我们在介绍如何从数据库中读取用户信息,当然还会涉及到更深入的东西,比如根据自己系统的需要自定义UserDetails和 UserDetailsService,这个只是让你对整个系统有个简单的了解,所以我们使用用户属性文件(users.properties)来存储用户信息:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 admin=admin,ROLE_SUPERVISOR
2 
3 user1=user1,ROLE_USER
4 
5 user2=user2,ROLE_USER
6 
7 user3=user3,disabled,ROLE_USER

    配置userDetailsService:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 <bean id="userDetailsService"
2 
3 class="org.springframework.security.userdetails.memory.InMemoryDaoImpl">
4      <property name="userProperties">
5         <bean class="org.springframework.beans.factory.config.PropertiesFactoryBean"
6           p:location
="/WEB-INF/users.properties"/>
7      </property>
8 </bean>

    InMemoryDaoImpl类是UserDetailsService接口的一个实现,它从属性文件里读取用户信息,Spring Security使用一个属性编辑器将用户信息为我们组织成一个 org.springframework.security.userdetails.memory.UserMap类的对象,我们也可以直接为它提供一个用户权限信息的列表,详见applicationContext-security.xml配置文件。

    UserMap字符串的每一行都用键值对的形式表示,前面是用户名,然后是等号,后面是赋予该用户的密码/权限等信息,它们使用逗号隔开。比如:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 admin=admin,ROLE_SUPERVISOR

    定义了一个名为admin的用户登录密码为admin,该用户拥有ROLE_SUPERVISOR权限,再如users.properties文件中配置的名为user3的用户登录密码为user3,该用户拥有ROLE_USER权限,disabled定义该用户不可用,为被激活(UserDetails 的isEnabled方法)。

即使是系统的开发者或者说是最终用户,都不应该看到系统中有明文的密码。所以,Spring Security考虑的还是很周到的,为我们提供的密码加密的功能。正如你在Dao认证提供者(DaoAuthenticationProvider)中看到的,passwordEncoder属性配置的就是一个密码加密程序(密码编码器)。这里我们使用MD5加密,可以看配置文件中的scott用户,你还能看出他的密码是什么吗?当然这里只是演示功能,其它用户还是没有改变,你可以自己试试。系统为我们提供了一些常用的密码编码器(这些编码器都位于 org.springframework.secu rity.providers.encoding包下):

    PlaintextPasswordEncoder(默认)——不对密码进行编码,直接返回未经改变的密码;

    Md4PasswordEncoder ——对密码进行消息摘要(MD4)编码;

    Md5PasswordEncoder ——对密码进行消息摘要(MD5)编码;

    ShaPasswordEncoder ——对密码进行安全哈希算法(SHA)编码。

    你可以根据需要选择合适的密码编码器,你也可以设置编码器的种子源(salt source)。一个种子源为编码提供种子(salt),或者称编码的密钥,这里不再赘述。

    这里附加介绍了不少东西,希望你还没有忘记在AuthenticationManager(认证管理器)中还配置了一个名为 sessionController的Bean,这个Bean可以阻止用户在进行了一次成功登录以后在进行一次成功的登录。在 applicationContext-security.xml配置文件添加sessionController的配置:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 <bean id="concurrentSessionController"
2 
3 class="org.springframework.security.concurrent.ConcurrentSessionControllerImpl"
4     p:maximumSessions="1"
5     p:exceptionIfMaximumExceeded="true"
6     p:sessionRegistry-ref="sessionRegistry"/>
7 <bean id="sessionRegistry"
8 
9 class="org.springframework.security.concurrent.SessionRegistryImpl"/>

    maximumSessions属性配置了只允许同一个用户登录系统一次,exceptionIfMaximumExceeded属性配置了在进行第二次登录是是否让第一次登录失效。这里设置为true不允许第二次登录。要让此功能生效,我们还需要在web.xml文件中添加一个监听器,以让Spring Security能获取Session的生命周期事件,配置如下:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 <listener>
2      <listener-class>
3         org.springframework.security.ui.session.HttpSessionEventPublisher
4      </listener-class>
5 </listener>

    HttpSessionEventPublisher类实现javax.servlet.http.HttpSessionListener接口,在 Session被创建的时候通过调用ApplicationContext的publishEvent(ApplicationEvent event)发布HttpSessionCreatedEvent类型的事件,HttpSessionCreatedEvent类继承自 org.springframework.context.ApplicationEvent类的子类 HttpSessionApplicationEvent抽象类。

    concurrentSessionController使用sessionRegistry来完成对发布的Session的生命周期事件的处理,org.springframework.security.concurrent.SessionRegistryImpl(实现了 SessionRegistry接口), SessionRegistryImpl类还实现了Spring Framework 的事件监听org.springframework.context.Application Listener接口,并实现了该接口定义的onApplicationEvent(ApplicationEvent event)方法用于处理Applic ationEvent类型的事件,如果你了解Spring Framework的事件处理,那么这里你应该可以很好的理解。

    认证管理器到此介绍完毕了,认证过程过滤器也介绍完了,接下来我们继续介绍过滤器链的下一个过滤器securityContextHolderAwareRequestFilter:

<!--<br /> <br /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br /> http://www.CodeHighlighter.com/<br /> <br /> -->1 <bean id="securityContextHolderAwareRequestFilter"
2     class="org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter"/>

    这个过滤器使用装饰模式(Decorate Model),装饰的HttpServletRequest对象。其Wapper是ServletRequest包装类 HttpServletRequestWrapper的子类(如SavedRequestAwareWrapper或 SecurityContextHolderAwareRequestWrapper),附上获取用户权限信息,request参数,headers 和 cookies 的方法。

    rememberMeProcessingFilter过滤器配置:

    <bean id="rememberMeProcessingFilter"

    class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter"

&nbs

分享到:
评论

相关推荐

    Crawlee - 一个用于 Python 的网页抓取和浏览器自动化库,用于构建可靠的爬虫 提取 AI、LLM、RAG 或 GPT 的数据 从网站下载 HTML、PDF、JPG、PNG

    Web scraping and browser automation librarylee 涵盖了端到端的抓取和爬取,并帮助您快速构建可靠的爬取工具。 Crawlee for Python 向早期采用者开放!即使使用默认配置,您的爬虫程序看起来也几乎像人类一样,并且不会受到现代机器人保护的监视。Crawlee 为您提供了工具,让您可以抓取网络上的链接、抓取数据并以机器可读的格式持久存储数据,而无需担心技术细节。而且,由于配置选项丰富,如果默认设置不适用,您可以调整 Crawlee 的几乎任何方面以满足您的项目需求。在Crawlee 项目网站上查看完整的文档、指南和示例我们还有一个 TypeScript 实现的 Crawlee,您可以探索并利用它来完成您的项目。请访问我们的 GitHub 存储库,获取有关GitHub 上 JS/TS 的 Crawlee 的更多信息。安装我们建议您访问Crawlee 文档中的简介教程以获取更多信息。Crawlee 可作为crawleePyPI 软件包使用。核心功能包含在基础软件包中,其他功能作为可选附加功能提供,以最大限度地减少软件包大小和依赖项。要安装

    用AWLUM进行灰色编码2^2n-QAM调制的精确率Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    Simple Run Blocker -应用上锁工具

    Simple Run Blocker -应用上锁工具

    基于springboot的库存管理系统的设计与实现

    基于springboot+vue的网上零食销售商城。适用于计算机类毕业设计,课程设计参考与学习用途。 系统设计考虑了企业在库存管理中的各种需求,提供了包括用户管理、商品管理、库存监控、订单处理、数据分析、客户关系维护以及系统安全与配置在内的核心功能模块。用户管理模块支持用户信息的增删改查以及角色和权限的分配,确保了系统的安全性和多级管理的便捷性。商品管理模块允许轻松录入和更新商品信息,自动化记录库存变动,为库存优化提供了数据支持。订单管理模块覆盖了订单的整个生命周期,从创建到发货再到退货,每个环节都得到了精细化管理。报表统计模块通过生成各类报表,为决策提供了数据支撑。客户管理模块则侧重于维护客户信息和购买历史,以便更好地服务客户。最后,系统设置模块允许管理员根据业务需求调整系统参数。整个系统的设计旨在帮助企业提升库存管理的效率和精确度。本文研究成果为企业提供了一套完备的库存管理解决方案。 关键词: 库存管理;Spring Boot;Vue.js;系统设计;数据库

    java面向对象 - 类与对象.doc

    java面向对象 - 类与对象 在Java编程语言中,面向对象编程(OOP)是一个核心概念。它强调以对象作为程序的基本单位,并将相关的数据和功能封装在对象中。类和对象是Java OOP的两个关键组成部分。 ### 类(Class) 类是一个模板或蓝图,它定义了对象的属性和行为。我们可以将类视为对象的类型或种类。通过类,我们可以创建(实例化)具有特定属性和行为的对象。 类的组成部分通常包括: 1. **成员变量**(属性):用于存储对象的状态或数据。 2. **方法**(行为):定义了对象可以执行的操作或功能。 3. **构造方法**:一种特殊类型的方法,用于在创建对象时初始化其状态。 4. **块**(如静态块、实例初始化块):用于执行类级别的初始化代码。 5. **嵌套类**:一个类可以包含其他类,这被称为嵌套或内部类。 ### 对象(Object) 对象是类的实例。它是根据类模板创建的具体实体,具有自己的状态和行为。每个对象都是其类的一个唯一实例,可以访问其类中定义的属性和方法。 创建对象的过程通常涉及以下几个步骤: 1. **声明**:指定对象的类型(即其所属的类

    雷达阵列天线的方向图,有结果截图,适合于初学者matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    Notepad-v2.20工具,是替代Notepad++的首选工具

    Notepad-v2.20工具,是替代Notepad++的首选工具

    项目管理软考基础知识点和冲刺要点.pdf

    项目管理软考基础知识点和冲刺要点

    月色场景嫦娥弹琴flash动画.zip

    月色场景嫦娥弹琴flash动画.zip

    具有恒定相对挥发度的标准双组分蒸馏塔模型 matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    ECharts柱状图-极坐标系下的堆叠柱状图2.rar

    图表效果及代码实现讲解链接:https://blog.csdn.net/zhangjiujiu/article/details/143997013

    原生js模仿新浪微博发布评论代码.rar

    原生js模仿新浪微博发布评论代码.rar

    重力排水罐物质平衡模型及实验结果 matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    音频过滤器 GUI Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    商务喷气机的 μ-合成自动着陆控制器Matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

    宏观数经济学期末考试试卷解析-经济管理-教学资料

    内容概要:本文档提供了对外经济贸易大学20XX-20XX学年第X学期《宏观经济学》期末考试的试卷,涵盖了单项选择题、名词解释、简答题和论述题,旨在测试学生对宏观经济学基础知识和理论的理解及应用能力。试题内容涉及国内生产总值、边际消费倾向、通货膨胀、财政政策、货币政策等多个概念及其政策意义。 适合人群:对外经济贸易大学或类似院校的学生,尤其是修读《宏观经济学》课程的学生,教师也可作为教学参考资料。 使用场景及目标:①帮助学生全面掌握《宏观经济学》的基础知识点,为考试复习做准备;②教师可用作课堂教学材料或考试命题的参考;③研究机构研究人员可借鉴试卷内容进行相关课题研究。 其他说明:试卷难度适中,题目覆盖面广,既考查学生的记忆能力,也强调理解和分析能力。

    数据库基本内容讲解和操作

    数据库基本内容讲解和操作

    计算机二级考试选择题练习模拟题70道及答案.doc

    计算机二级考试选择题练习模拟题70道及答案 所看及所得 内容有生成式AI自动出题并解析答案 欢迎爱学习的朋友下载

    c++语言编程用遗传算法解决背包问题的源代码

    背包问题的求解。本资源是c++语言编程用遗传算法解决背包问题的源代码。代码可以自己设置物品的数量、种群的大小。进化次数、交叉概率、变异概率等参数。背包问题是给定一组物品,每个物品都有一个重量和一个价值,确定在不超过背包最大载重量的情况下,应该选择哪些物品,使得这些物品的总价值最大。

    中创建系统级简化参数化铰接式机器人模型 matlab代码.rar

    1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。 替换数据可以直接使用,注释清楚,适合新手

Global site tag (gtag.js) - Google Analytics