- 浏览: 1045034 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (538)
- 奇文共赏 (36)
- spring (13)
- hibernate (10)
- AOP/Aspectj (9)
- spring security (7)
- lucence (5)
- compass (3)
- jbmp (2)
- jboss rule(drools) (0)
- birt (1)
- jasper (1)
- cxf (3)
- flex (98)
- webgis (6)
- 设计模式 (1)
- 代码重构 (2)
- log4j (1)
- tomcat (9)
- 神品音乐 (1)
- 工作计划 (2)
- appfuse (1)
- svn (4)
- 寻章摘句 (3)
- eclipse (10)
- arcgis api for flex (1)
- 算法 (5)
- opengis-cs (1)
- bug心得 (13)
- 图标 (1)
- software&key (14)
- java (17)
- 搞笑视频 (13)
- sqlserver (9)
- postgresql (1)
- postgis (0)
- geoserver (5)
- 日子 (50)
- 水晶报表 (1)
- 绝对电影 (3)
- Alternativa3D (1)
- 酷站大全 (10)
- c++ (5)
- oracle (17)
- oracle spatial (25)
- flashbuilder4 (3)
- TweenLite (1)
- DailyBuild (6)
- 华山论贱 (5)
- 系统性能 (5)
- 经典古文 (6)
- SOA/SCA/OSGI (6)
- jira (2)
- Hadoop生态圈(hadoop/hbase/pig/hive/zookeeper) (37)
- 风水 (1)
- linux操作基础 (17)
- 经济 (4)
- 茶 (3)
- JUnit (1)
- C# dotNet (1)
- netbeans (1)
- Java2D (1)
- QT4 (1)
- google Test/Mock/AutoTest (3)
- maven (1)
- 3d/OSG (1)
- Eclipse RCP (3)
- CUDA (1)
- Access control (0)
- http://linux.chinaunix.net/techdoc/beginner/2008/01/29/977725.shtml (1)
- redis (1)
最新评论
-
dove19900520:
朋友,你确定你的标题跟文章内容对应???
tomcat控制浏览器不缓存 -
wussrc:
我只想说牛逼,就我接触过的那点云计算的东西,仔细想想还真是这么 ...
别样解释云计算,太TM天才跨界了 -
hw_imxy:
endpoint="/Hello/messagebr ...
flex+java代码分两个工程 -
gaohejie:
rsrsdgrfdh坎坎坷坷
Flex 与 Spring 集成 -
李涤尘:
谢谢。不过说得有点太罗嗦了。
Oracle数据库数据的导入及导出(转)
http://forum.springside.org.cn/viewthread.php?tid=3281
平台:
Windows
JDK 1.5
Tomcat 5.5.20
ApacheDS 1.0.2
Spring Framework 2.5.5
Spring Security 2.0.3
CAS Server 3.3
Java CAS Client 3.1.3
配置过程
1 安装JDK,Tomcat,ApacheDS
一般来说,JDK,tomcat均采用zip包,拷贝后设置系统环境变量,不赘述。
ApacheDS安装完成后,缺省的LDAP端口采用的是10389,到其安装目录下conf子目录中找到server.xml,可以修改为标准的389端口,便于后面的测试。
另外,需要注意的是,为了便于管理,最好安装一个LDAP管理客户端,推荐LDAP Browser.
2 安装CAS Server
直接将下载来的cas server解包,在modules子目录下面有一个cas-server-webapp-3.3.war的文件,用压缩软件将其打开,解压到cas目录中,
拷贝到tomcat的webapps目录之下。
2.1 让CAS Server使用LDAP目录,下面的配置实用了刚刚本地安装的ApacheDS,端口没有明确指定,说明使用缺省端口
修改authenticationHandlers为下面的样子
添加LDAP contextSource的bean定义
2.2 配置Tomcat 5.5.20的SSL
首先,需要创建证书,并指定Tomcat使用该证书,然后将证书导入到JRE环境
该过程可以使用keytool工具完成,我将其过程编写为一个批处理文件,直接使用即可
读者在使用过程中,需要根据自己的情况修改。比如第一行的删除证书,是便于重新生成证书,再创建添加的,如果首次使用,这行则需要屏蔽掉。另外,如果密码和jdk目录不同,也请修改。
【注意】在创建证书时,当系统提示你让输入姓名的时候,一定要填写要部署的主机名,Spring Security会在验证用户ticket的时候出现异常,提示类似"host name must be localhost"之类的信息。
好了,证书创建导入完毕,可以在tomcat中启用,注意不同的tomcat也许配置有细微差别,请注意tomcat的server.xml文档中的说明。
在5.5.20中,我们配置如下
2.3 测试CAS Server
启动Tomcat,在浏览器中输入https://localhost:8444/cas
浏览器中将显示cas服务器的登录路径,输入ApacheDS的缺省管理员帐号admin,密码secret,如果提示登录成功,则说明配置无误。
2.4 配置Speing security 2.0.3
配置Spring中关于安全的Bean,代码如下
需要说明的是<bean id="userDetailsService" class="com.hm.org.service.UserDetailServiceImpl" />这个bean,这个bean实现了UserDetailService接口,即实现了public UserDetails loadUserByUsername(String userName)方法,由于我们只是使用CAS Server进行身份认证,而关于用户的其他信息,还是存储在类似关系数据库这种系统中,因此,我们需要实现自己的 userDetailsService,很简单,这里不列出代码。
该配置中几点需要说明,serviceProperties bean中,service属性,有作为回调实现Single Sign Out的作用。sendRenew属性如果为true要求目标应用一定要显式登录,而不接受SSO,也就是说即使登录了CAS,当前应用也不承认,需要你再次提交用户凭证信息,这对于保护特殊的应用有很大作用,比如用户修改口令等私密信息,即可以采取这种措施。
2.5 配置Single Sign Out
即从任何一点退出系统,则所有的应用应该全部退出。目前版本的CAS服务器支持了该项功能,但Spring Security还不能很好支持(我查阅了Spring Seurity中关于该功能的内容,Scott看上去不太理解哪里没有完成,他认为可以很好支持CAS的Single Sign Out,但实际却是存在一定问题。)
当前版本的Spring security,2.0.3,有单一退出支持,不过我的测试是不成功。具体配置方法为
在web.xml中添加如下的代码
2.6 测试SSO
这样,所有配置均已经完成,测试SSO,发现登录任何一个应用,则会定向到CAS服务器的登录界面,然后访问其他应用,不需要再次登录。然而,遗憾的是,但推出CAS服务器时,应用并没有退出,其登录信息已经保存在各自的Session中,虽然我们看到CAS在退出时,向目标service发出了退出消息(打开CAS Server的相关日志,设置为debug可以看到),但Spring securiy没有反应。请参考http://www.ja-sig.org/wiki/display/CASUM/Single+Sign+Out查看CAS的具体行为。
3 一点说明
关于本文的叙述,也可能存在谬误,特别是关于Single Sign Out为何不成功的原因,只是个人的判断。也许是配置不当。
4 附录
4.1 CAS登录和验证不使用ssl通道的方法
在cas-servelet.xml中,将ticketGrantingTicketCookieGenerator和warnCookieGenerator中的cookieSecure属性置为false
4.2 如何在CAS服务器端关闭single sign out(CAS3.2+)
修改WEB-INF/spring-configuration/argumentConfiguration.xml
----------------------------------------
回复本贴是,2.0.4已经出来一段时间了,大家看看这个版本SingleSignOut是否可以成功。
另外,下面是一段jira上关于这个问题的回帖,有参考价值
I think the confusion is how to add the logout filter to the XML configuration file. I think Martino thinks the current filter/listener combo isn't real because there aren't any examples of how to set it up with Spring Security on the CAS website. The real issue is that you need to have the logout filter come before the CAS filter in the security.xml or before the filter chain invocation in the web.xml. The way I do it is in the security.xml.
Fine grained config:
<bean id="securityFilter" class="org.springframework.security.util.FilterChainProxy">
<sec:filter-chain pattern="/**" filters="channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter,casSingleSignOutFilter,casProcessingFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor"/>
</bean>
<bean id="casSingleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
Default config:
<bean id="casSingleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter">
<sec:custom-filter before="CAS_PROCESSING_FILTER"/>
</bean>
Then you also need to add the listener to your web.xml. The listener maps the service tickets to the HttpSession.
Hope this helps.
-Matt
----本人还没有校验这篇文章,呵呵
平台:
Windows
JDK 1.5
Tomcat 5.5.20
ApacheDS 1.0.2
Spring Framework 2.5.5
Spring Security 2.0.3
CAS Server 3.3
Java CAS Client 3.1.3
配置过程
1 安装JDK,Tomcat,ApacheDS
一般来说,JDK,tomcat均采用zip包,拷贝后设置系统环境变量,不赘述。
ApacheDS安装完成后,缺省的LDAP端口采用的是10389,到其安装目录下conf子目录中找到server.xml,可以修改为标准的389端口,便于后面的测试。
另外,需要注意的是,为了便于管理,最好安装一个LDAP管理客户端,推荐LDAP Browser.
2 安装CAS Server
直接将下载来的cas server解包,在modules子目录下面有一个cas-server-webapp-3.3.war的文件,用压缩软件将其打开,解压到cas目录中,
拷贝到tomcat的webapps目录之下。
2.1 让CAS Server使用LDAP目录,下面的配置实用了刚刚本地安装的ApacheDS,端口没有明确指定,说明使用缺省端口
修改authenticationHandlers为下面的样子
<property name="authenticationHandlers"> <list> <bean class="org.jasig.cas.authentication.handler.support.HttpBasedServiceCredentialsAuthenticationHandler" p:httpClient-ref="httpClient" /> <bean class="org.jasig.cas.adaptors.ldap.BindLdapAuthenticationHandler"> <property name="filter" value="uid=%u" /> <property name="searchBase" value="ou=system" /> <property name="contextSource" ref="contextSource" /> </bean> </list> </property>
添加LDAP contextSource的bean定义
<bean id="contextSource" class="org.jasig.cas.adaptors.ldap.util.AuthenticatedLdapContextSource"> <property name="urls"> <list> <value>ldap://localhost/</value> </list> </property> <property name="userName" value="uid=admin,ou=system" /> <property name="password" value="secret" /> <property name="baseEnvironmentProperties"> <map> <entry> <key> <value> java.naming.security.authentication </value> </key> <value>simple</value> </entry> </map> </property> </bean>
2.2 配置Tomcat 5.5.20的SSL
首先,需要创建证书,并指定Tomcat使用该证书,然后将证书导入到JRE环境
该过程可以使用keytool工具完成,我将其过程编写为一个批处理文件,直接使用即可
keytool -delete -alias tomcat -keystore D:/java/jdk1.5.0_07/jre/lib/security/cacerts -storepass changeit del server.keystore keytool -genkey -alias tomcat -keyalg RSA -keypass password -storepass password -keystore server.keystore -validity 3600 del server.cer keytool -export -trustcacerts -alias tomcat -file server.cer -keystore server.keystore -storepass password keytool -import -trustcacerts -alias tomcat -file server.cer -keystore D:/java/jdk1.5.0_07/jre/lib/security/cacerts -storepass changeit
读者在使用过程中,需要根据自己的情况修改。比如第一行的删除证书,是便于重新生成证书,再创建添加的,如果首次使用,这行则需要屏蔽掉。另外,如果密码和jdk目录不同,也请修改。
【注意】在创建证书时,当系统提示你让输入姓名的时候,一定要填写要部署的主机名,Spring Security会在验证用户ticket的时候出现异常,提示类似"host name must be localhost"之类的信息。
好了,证书创建导入完毕,可以在tomcat中启用,注意不同的tomcat也许配置有细微差别,请注意tomcat的server.xml文档中的说明。
在5.5.20中,我们配置如下
<Connector acceptCount="100" clientAuth="false" disableUploadTimeout="true" enableLookups="false" keystoreFile="d:/java/apache-tomcat-5.5.20/server.keystore" keystorePass="password" maxHttpHeaderSize="8192" maxSpareThreads="75" maxThreads="150" minSpareThreads="25" port="8443" protocol="org.apache.coyote.http11.Http11Protocol" scheme="https" secure="true" sslProtocol="TLS"/>
2.3 测试CAS Server
启动Tomcat,在浏览器中输入https://localhost:8444/cas
浏览器中将显示cas服务器的登录路径,输入ApacheDS的缺省管理员帐号admin,密码secret,如果提示登录成功,则说明配置无误。
2.4 配置Speing security 2.0.3
配置Spring中关于安全的Bean,代码如下
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:sec="http://www.springframework.org/schema/security" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring -security-2.0.xsd" default-autowire="byName" default-lazy-init="true"> <sec:http entry-point-ref="casProcessingFilterEntryPoint"> <sec:intercept-url pattern="/index.jsp" access="ROLE_USER" /> <sec:intercept-url pattern="/admin/**" access="ROLE_USER" /> <sec:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" /> <sec:logout logout-success-url="/cas-logout.jsp"/> <sec:anonymous /> </sec:http> <sec:authentication-manager alias="authenticationManager"/> <bean id="casProcessingFilter" class="org.springframework.security.ui.cas.CasProcessingFilter"> <sec:custom-filter after="CAS_PROCESSING_FILTER"/> <property name="authenticationManager" ref="authenticationManager"/> <property name="authenticationFailureUrl" value="/casfailed.jsp"/> <property name="defaultTargetUrl" value="/"/> </bean> <bean id="casProcessingFilterEntryPoint" class="org.springframework.security.ui.cas.CasProcessingFilterEntryPoint"> <property name="loginUrl" value="https://localhost:8443/cas/login"/> <property name="serviceProperties" ref="serviceProperties"/> </bean> <bean id="casAuthenticationProvider" class="org.springframework.security.providers.cas.CasAuthenticationProvider"> <sec:custom-authentication-provider /> <property name="userDetailsService" ref="userDetailsService"/> <property name="serviceProperties" ref="serviceProperties" /> <property name="ticketValidator"> <bean class="org.jasig.cas.client.validation.Cas20ServiceTicketValidator"> <constructor-arg index="0" value="https://localhost:8443/cas" /> </bean> </property> <property name="key" value="an_id_for_this_auth_provider_only"/> </bean> <bean id="userDetailsService" class="com.hm.org.service.UserDetailServiceImpl" /> <bean id="serviceProperties" class="org.springframework.security.ui.cas.ServiceProperties"> <property name="service" value="http://localhost/cis2/j_spring_cas_security_check"/> <property name="sendRenew" value="false"/> </bean> </beans>
需要说明的是<bean id="userDetailsService" class="com.hm.org.service.UserDetailServiceImpl" />这个bean,这个bean实现了UserDetailService接口,即实现了public UserDetails loadUserByUsername(String userName)方法,由于我们只是使用CAS Server进行身份认证,而关于用户的其他信息,还是存储在类似关系数据库这种系统中,因此,我们需要实现自己的 userDetailsService,很简单,这里不列出代码。
该配置中几点需要说明,serviceProperties bean中,service属性,有作为回调实现Single Sign Out的作用。sendRenew属性如果为true要求目标应用一定要显式登录,而不接受SSO,也就是说即使登录了CAS,当前应用也不承认,需要你再次提交用户凭证信息,这对于保护特殊的应用有很大作用,比如用户修改口令等私密信息,即可以采取这种措施。
2.5 配置Single Sign Out
即从任何一点退出系统,则所有的应用应该全部退出。目前版本的CAS服务器支持了该项功能,但Spring Security还不能很好支持(我查阅了Spring Seurity中关于该功能的内容,Scott看上去不太理解哪里没有完成,他认为可以很好支持CAS的Single Sign Out,但实际却是存在一定问题。)
当前版本的Spring security,2.0.3,有单一退出支持,不过我的测试是不成功。具体配置方法为
在web.xml中添加如下的代码
<filter> <filter-name>CAS Single Sign Out Filter</filter-name> <filter-class>org.jasig.cas.client.session.SingleSignOutFilter</filter-class> </filter> <filter-mapping> <filter-name>CAS Single Sign Out Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>org.jasig.cas.client.session.SingleSignOutHttpSessionListener</listener-class> </listener>
2.6 测试SSO
这样,所有配置均已经完成,测试SSO,发现登录任何一个应用,则会定向到CAS服务器的登录界面,然后访问其他应用,不需要再次登录。然而,遗憾的是,但推出CAS服务器时,应用并没有退出,其登录信息已经保存在各自的Session中,虽然我们看到CAS在退出时,向目标service发出了退出消息(打开CAS Server的相关日志,设置为debug可以看到),但Spring securiy没有反应。请参考http://www.ja-sig.org/wiki/display/CASUM/Single+Sign+Out查看CAS的具体行为。
3 一点说明
关于本文的叙述,也可能存在谬误,特别是关于Single Sign Out为何不成功的原因,只是个人的判断。也许是配置不当。
4 附录
4.1 CAS登录和验证不使用ssl通道的方法
在cas-servelet.xml中,将ticketGrantingTicketCookieGenerator和warnCookieGenerator中的cookieSecure属性置为false
4.2 如何在CAS服务器端关闭single sign out(CAS3.2+)
修改WEB-INF/spring-configuration/argumentConfiguration.xml
<bean id="casArgumentExtractor" class="org.jasig.cas.web.support.CasArgumentExtractor"> <property name="disableSingleSignOut"> <value>true</value> </property> </bean>
----------------------------------------
回复本贴是,2.0.4已经出来一段时间了,大家看看这个版本SingleSignOut是否可以成功。
另外,下面是一段jira上关于这个问题的回帖,有参考价值
I think the confusion is how to add the logout filter to the XML configuration file. I think Martino thinks the current filter/listener combo isn't real because there aren't any examples of how to set it up with Spring Security on the CAS website. The real issue is that you need to have the logout filter come before the CAS filter in the security.xml or before the filter chain invocation in the web.xml. The way I do it is in the security.xml.
Fine grained config:
<bean id="securityFilter" class="org.springframework.security.util.FilterChainProxy">
<sec:filter-chain pattern="/**" filters="channelProcessingFilter,httpSessionContextIntegrationFilter,logoutFilter,casSingleSignOutFilter,casProcessingFilter,securityContextHolderAwareRequestFilter,exceptionTranslationFilter,filterInvocationInterceptor"/>
</bean>
<bean id="casSingleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter"/>
Default config:
<bean id="casSingleSignOutFilter" class="org.jasig.cas.client.session.SingleSignOutFilter">
<sec:custom-filter before="CAS_PROCESSING_FILTER"/>
</bean>
Then you also need to add the listener to your web.xml. The listener maps the service tickets to the HttpSession.
Hope this helps.
-Matt
----本人还没有校验这篇文章,呵呵
发表评论
-
SSO(Single Sign-on) in Action(上篇)
2009-08-11 09:09 1789http://www.blogjava.net/securit ... -
Spring in Action中文版--11.2.4 基于Acegi和Yale CAS实现单次登录
2009-08-05 10:33 2263http://book.csdn.net/bookfiles/ ... -
Spring Security学习总结二
2008-09-08 17:03 1117http://www.blogjava.net/redhatl ... -
Spring Security学习总结一
2008-09-08 17:02 1010http://www.blogjava.net/redhatl ... -
acegi到spring security的转换方式
2008-09-08 17:01 1180acegi到spring security的转换方式 http ... -
中文说明
2008-09-02 16:15 974[url]http://www.family168.com/t ...
相关推荐
单一登录踢人效果是Web应用程序中的一种常见需求,通过创建Session监听类和实现登录方法和踢人效果实现,可以实现单一登录踢人效果。该功能可以提高系统的安全性和可靠性,防止用户在不同设备或浏览器中同时登录同一...
- **单一登录退出**:用户登出时,应同时失效所有相关系统的登录状态。 - **令牌刷新**:定期更新令牌,提高安全性。 - **异常处理和日志记录**:捕获和记录认证、授权过程中的异常,便于问题排查。 通过以上...
4. **单一注销功能**:用户执行一次退出操作即可终止对多个应用程序或网站的访问。 5. **会话管理**:默认情况下,每个应用都会验证由SSO系统管理的会话是否有效,然后给予用户访问权限。必要时,各应用可以独立设置...
Vue Shop 是一个基于 Vue.js 框架构建的...通过深入研究 Vue Shop 项目,开发者不仅能学习到 Vue.js 的基础和最佳实践,还能掌握前端身份验证的实现方式,这对于构建任何需要用户登录功能的 web 应用都是非常有价值的。
Ruby编写Puma Web服务器v6.4.2是一款高效能且专为并发设计的Web服务器,主要用于Ruby/Rack应用。Puma服务器以其简洁、快速、多线程和高并发性著称,它能够轻松处理大量并发请求,提升了Ruby应用的性能。 首先,我们...
- Django内置了用户认证系统,可通过调用相关API实现用户登录、注销等功能。 - **关上窗户** - 用户注销后清除Session,确保安全。 #### Django 模型 - **设计系统表** - 使用ORM定义数据库模型。 - 自定义...
Cas(Central Authentication Service)是一种基于Web的单一登录(Single Sign-On, SSO)协议,用于在多个应用系统间实现统一的认证服务。Cas的核心功能是让用户只需要在一个地方验证身份,之后就能访问所有集成的...
5. 用户认证和授权:了解如何实现简单的登录系统,以及如何控制不同用户对页面的访问权限。 6. Web表单控件:掌握如何在ASP.NET页面上使用文本框、按钮、验证控件等进行用户交互。 7. 事件处理:学习如何编写代码...
CAS是一种基于Web的身份验证协议,它允许用户通过单一登录过程访问多个应用系统,提高了用户体验并简化了身份管理。在PHP中使用CAS客户端,我们可以轻松地将CAS SSO功能添加到我们的Web应用程序中。 ### 1. CAS协议...
这个“Android_ActionBar-Service”项目显然旨在教授开发者如何在2015年秋季CIS 490-75移动Web应用程序开发课程中有效地使用ActionBar以及相关的服务概念。 首先,让我们深入理解ActionBar。在Android系统中,...
CAS(Central Authentication Service)是一种基于Web的单一登录(Single Sign-On, SSO)协议,用于在网络上为用户提供统一的认证服务。这个"cas-client-3.2.1+cas-server-3.4.10"组合涉及到CAS客户端和服务器的两个...
本文将深入探讨Cloud-ids的核心技术和应用,以帮助我们更好地理解Web安全、身份与访问管理以及风险评估的重要性。 首先,Cloud-ids基于智能分析技术,利用大数据和机器学习来实现对Web安全的深度防御。传统的二维...
在 web3.0 的世界里,用户不再依赖于单一的服务提供商,而是通过区块链技术和分布式应用程序(DApps)来控制自己的信息和资产。 【DAO】(Decentralized Autonomous Organization) 是一种基于区块链的自治组织,它的...
3. **单一退出**:用户在一处注销时,应能自动从所有关联的系统中注销。 4. **访问控制**:实施细粒度的权限控制,确保用户只能访问他们被授权的资源。 5. **审计跟踪**:记录并分析SSO活动,以便在出现问题时进行...
Web测试是确保网页应用功能正常、用户体验良好以及系统安全的关键环节。以下是对Web测试概念的详细解释: **界面测试** 界面测试关注用户看到和交互的所有元素。这包括文字内容、样式一致性、按钮、文本框、单选框...
新闻管理系统model1模式是一种常见的软件开发模式,尤其在Web应用中被广泛应用。在这个项目中,model1模式被用来构建一个具备用户登录验证、新闻查询、新闻添加以及安全退出功能的系统。下面将详细阐述model1模式的...
- **单元测试框架**:适用于对单一组件进行测试。 - **测试用例编写**:遵循一定的结构和规范。 **6.2 Testing in Django** - **6.2.1 A simple example** - 通过简单的示例展示如何编写测试用例。 - **6.2.2 Run...
综上所述,“认我测”在线认证检测系统,率先填补了认证检测领域移动端的空缺,提供了Web浏览器+移动端的双端访问模式,给用户提供了多种访问途径,真正实现了用户和检测机构的随时随地在线下单检测。 关键词:...
此外,为了使应用程序更加完善,开发者还需要对各种组件进行调整和优化,以及实现退出封装器,确保程序可以优雅地退出。通过封装退出功能,可以确保程序在退出前能够正确地释放资源,避免潜在的内存泄露等问题。 在...