- 浏览: 79586 次
最新评论
-
zhangjie3140:
感谢分享
tabhost里解决按键事件捕获的问题 -
honghe:
请问我重写了 onCreateWindow,但处理window ...
在webview中访问互联网应用,碰到弹出窗口怎么办? -
肖默it:
解决了我的问题,感谢楼主的分享!
tabhost里解决按键事件捕获的问题 -
hecal:
太感谢了~~
tabhost里解决按键事件捕获的问题 -
guogzhao:
注意在if判断中要加一个event.getAction() = ...
tabhost里解决按键事件捕获的问题
使用 Spring 更好地处理 Struts 动作
2005 年 10 月 11 日
Struts Recipes 的合著者 George Franciscus 将介绍另一个重大的 Struts 整合窍门 —— 这次是将 Struts 应用程序导入 Spring 框架。请跟随 George,他将向您展示如何改变 Struts 动作,使得管理 Struts 动作就像管理 Spring beans 那样。结果是一个增强的 web 框架,这个框架可以方便地利用 Spring AOP 的优势。<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
您肯定已经听说过控制反转 (IOC) 设计模式,因为很长一段时间以来一直在流传关于它的信息。如果您在任何功能中使用过 Spring 框架,那么您就知道其原理的作用。在本文中,我利用这一原理把一个 Struts 应用程序注入 Spring 框架,您将亲身体会到 IOC 模式的强大。
将一个 Struts 应用程序整合进 Spring 框架具有多方面的优点。首先,Spring 是为解决一些关于 JEE 的真实世界问题而设计的,比如复杂性、低性能和可测试性,等等。第二,Spring 框架包含一个 AOP 实现,允许您将面向方面技术应用于面向对象的代码。第三,一些人可能会说 Spring 框架只有处理 Struts 比 Struts 处理自己好。但是这是观点问题,我演示三种将 Struts 应用程序整合到 Spring 框架的方法后,具体由您自己决定使用哪一种。
我所演示的方法都是执行起来相对简单的,但是它们却具有明显不同的优点。我为每一种方法创建了一个独立而可用的例子,这样您就可以完全理解每种方法。请参阅 下载 部分获得完整例子源代码。请参阅 参考资料,下载 Struts MVC 和 Spring 框架。
Spring 的创立者 Rod Johnson 以一种批判的眼光看待 Java™ 企业软件开发,并且提议很多企业难题都能够通过战略地使用 IOC 模式(也称作依赖注入)来解决。当 Rod 和一个具有奉献精神的开放源码开发者团队将这个理论应用于实践时,结果就产生了 Spring 框架。简言之,Spring 是一个轻型的容器,利用它可以使用一个外部 XML 配置文件方便地将对象连接在一起。每个对象都可以通过显示一个 JavaBean 属性收到一个到依赖对象的引用,留给您的简单任务就只是在一个 XML 配置文件中把它们连接好。
|
依赖注入是一个强大的特性,但是 Spring 框架能够提供更多特性。Spring 支持可插拔的事务管理器,可以给您的事务处理提供更广泛的选择范围。它集成了领先的持久性框架,并且提供一个一致的异常层次结构。Spring 还提供了一种使用面向方面代码代替正常的面向对象代码的简单机制。
Spring AOP 允许您使用拦截器 在一个或多个执行点上拦截应用程序逻辑。加强应用程序在拦截器中的日志记录逻辑会产生一个更可读的、实用的代码基础,所以拦截器广泛用于日志记录。您很快就会看到,为了处理横切关注点,Spring AOP 发布了它自己的拦截器,您也可以编写您自己的拦截器。
|
|
与 Struts 相似,Spring 可以作为一个 MVC 实现。这两种框架都具有自己的优点和缺点,尽管大部分人同意 Struts 在 MVC 方面仍然是最好的。很多开发团队已经学会在时间紧迫的时候利用 Struts 作为构造高品质软件的基础。Struts 具有如此大的推动力,以至于开发团队宁愿整合 Spring 框架的特性,而不愿意转换成 Spring MVC。没必要进行转换对您来说是一个好消息。Spring 架构允许您将 Struts 作为 Web 框架连接到基于 Spring 的业务和持久层。最后的结果就是现在一切条件都具备了。
在接下来的小窍门中,您将会了解到三种将 Struts MVC 整合到 Spring 框架的方法。我将揭示每种方法的缺陷并且对比它们的优点。 一旦您了解到所有三种方法的作用,我将会向您展示一个令人兴奋的应用程序,这个程序使用的是这三种方法中我最喜欢的一种。
|
|
接下来的每种整合技术(或者窍门)都有自己的优点和特点。我偏爱其中的一种,但是我知道这三种都能够加深您对 Struts 和 Spring 的理解。在处理各种不同情况的时候,这将给您提供一个广阔的选择范围。方法如下:
- 使用 Spring 的
ActionSupport
类整合 Structs - 使用 Spring 的
DelegatingRequestProcessor
覆盖 Struts 的RequestProcessor
- 将 Struts
Action
管理委托给 Spring 框架
无论您使用哪种技术,都需要使用 Spring 的 ContextLoaderPlugin
为 Struts 的 ActionServlet
装载 Spring 应用程序环境。就像添加任何其他插件一样,简单地向您的 struts-config.xml 文件添加该插件,如下所示:
<plug-in className= "org.springframework.web.struts.ContextLoaderPlugIn"> <set-property property= "contextConfigLocation" value="/WEB-INF/beans.xml"/> </plug-in> |
前面已经提到过,在 下载 部分,您能够找到这三个完全可使用的例子的完整源代码。每个例子都为一个书籍搜索应用程序提供一种不同的 Struts 和 Spring 的整合方法。您可以在这里看到例子的要点,但是您也可以下载应用程序以查看所有的细节。
|
|
窍门 1. 使用 Spring 的 ActionSupport
手动创建一个 Spring 环境是一种整合 Struts 和 Spring 的最直观的方式。为了使它变得更简单,Spring 提供了一些帮助。为了方便地获得 Spring 环境,org.springframework.web.struts.ActionSupport
类提供了一个 getWebApplicationContext()
方法。您所做的只是从 Spring 的 ActionSupport
而不是 Struts Action
类扩展您的动作,如清单 1 所示:
清单 1. 使用 ActionSupport 整合 Struts
package ca.nexcel.books.actions; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.DynaActionForm; import org.springframework.context.ApplicationContext; import org.springframework.web.struts.ActionSupport; import ca.nexcel.books.beans.Book; import ca.nexcel.books.business.BookService; public class SearchSubmit extends ActionSupport { |(1) public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { DynaActionForm searchForm = (DynaActionForm) form; String isbn = (String) searchForm.get("isbn"); //the old fashion way //BookService bookService = new BookServiceImpl(); ApplicationContext ctx = getWebApplicationContext(); |(2) BookService bookService = (BookService) ctx.getBean("bookService"); |(3) Book book = bookService.read(isbn.trim()); if (null == book) { ActionErrors errors = new ActionErrors(); errors.add(ActionErrors.GLOBAL_ERROR,new ActionError ("message.notfound")); saveErrors(request, errors); return mapping.findForward("failure") ; } request.setAttribute("book", book); return mapping.findForward("success"); } } |
让我们快速思考一下这里到底发生了什么。在 (1) 处,我通过从 Spring 的 ActionSupport
类而不是 Struts 的 Action
类进行扩展,创建了一个新的 Action
。在 (2) 处,我使用 getWebApplicationContext()
方法获得一个 ApplicationContext
。为了获得业务服务,我使用在 (2) 处获得的环境在 (3) 处查找一个 Spring bean。
这种技术很简单并且易于理解。不幸的是,它将 Struts 动作与 Spring 框架耦合在一起。如果您想替换掉 Spring,那么您必须重写代码。并且,由于 Struts 动作不在 Spring 的控制之下,所以它不能获得 Spring AOP 的优势。当使用多重独立的 Spring 环境时,这种技术可能有用,但是在大多数情况下,这种方法不如另外两种方法合适。
|
|
将 Spring 从 Struts 动作中分离是一个更巧妙的设计选择。分离的一种方法是使用 org.springframework.web.struts.DelegatingRequestProcessor
类来覆盖 Struts 的 RequestProcessor
处理程序,如清单 2 所示:
清单 2. 通过 Spring 的 DelegatingRequestProcessor 进行整合
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="searchForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="isbn" type="java.lang.String"/>
</form-bean>
</form-beans>
<global-forwards type="org.apache.struts.action.ActionForward">
<forward name="welcome" path="/welcome.do"/>
<forward name="searchEntry" path="/searchEntry.do"/>
<forward name="searchSubmit" path="/searchSubmit.do"/>
</global-forwards>
<action-mappings>
<action path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
<action path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
<action path="/searchSubmit"
type="ca.nexcel.books.actions.SearchSubmit"
input="/searchEntry.do"
validate="true"
name="searchForm">
<forward name="success" path="/WEB-INF/pages/detail.jsp"/>
<forward name="failure" path="/WEB-INF/pages/search.jsp"/>
</action>
</action-mappings>
<message-resources parameter="ApplicationResources"/>
<controller processorClass="org.springframework.web.struts.
DelegatingRequestProcessor"/> |(1)
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="csntextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>
</struts-config>
|
我利用了 <controller>
标记来用 DelegatingRequestProcessor
覆盖默认的 Struts RequestProcessor
。下一步是在我的 Spring 配置文件中注册该动作,如清单 3 所示:
清单 3. 在 Spring 配置文件中注册一个动作
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/>
<bean name="/searchSubmit"
class="ca.nexcel.books.actions.SearchSubmit"> |(1)
<property name="bookService">
<ref bean="bookService"/>
</property>
</bean>
</beans>
|
注意:在 (1) 处,我使用名称属性注册了一个 bean,以匹配 struts-config 动作映射名称。SearchSubmit
动作揭示了一个 JavaBean 属性,允许 Spring 在运行时填充属性,如清单 4 所示:
清单 4. 具有 JavaBean 属性的 Struts 动作
package ca.nexcel.books.actions; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.DynaActionForm; import ca.nexcel.books.beans.Book; import ca.nexcel.books.business.BookService; public class SearchSubmit extends Action { private BookService bookService; public BookService getBookService() { return bookService; } public void setBookService(BookService bookService) { | (1) this.bookService = bookService; } public ActionForward execute( ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { DynaActionForm searchForm = (DynaActionForm) form; String isbn = (String) searchForm.get("isbn"); Book book = getBookService().read(isbn.trim()); |(2) if (null == book) { ActionErrors errors = new ActionErrors(); errors.add(ActionErrors.GLOBAL_ERROR,new ActionError("message.notfound")); saveErrors(request, errors); return mapping.findForward("failure") ; } request.setAttribute("book", book); return mapping.findForward("success"); } } |
在清单 4 中,您可以了解到如何创建 Struts 动作。在 (1) 处,我创建了一个 JavaBean 属性。DelegatingRequestProcessor
自动地配置这种属性。这种设计使 Struts 动作并不知道它正被 Spring 管理,并且使您能够利用 Sping 的动作管理框架的所有优点。由于您的 Struts 动作注意不到 Spring 的存在,所以您不需要重写您的 Struts 代码就可以使用其他控制反转容器来替换掉 Spring。
DelegatingRequestProcessor
方法的确比第一种方法好,但是仍然存在一些问题。如果您使用一个不同的 RequestProcessor
,则需要手动整合 Spring 的 DelegatingRequestProcessor
。添加的代码会造成维护的麻烦并且将来会降低您的应用程序的灵活性。此外,还有过一些使用一系列命令来代替 Struts RequestProcessor
的传闻。 这种改变将会对这种解决方法的使用寿命造成负面的影响。
|
|
一个更好的解决方法是将 Strut 动作管理委托给 Spring。您可以通过在 struts-config
动作映射中注册一个代理来实现。代理负责在 Spring 环境中查找 Struts 动作。由于动作在 Spring 的控制之下,所以它可以填充动作的 JavaBean 属性,并为应用诸如 Spring 的 AOP 拦截器之类的特性带来了可能。
清单 5 中的 Action
类与清单 4 中的相同。但是 struts-config 有一些不同:
清单 5. Spring 整合的委托方法
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="searchForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="isbn" type="java.lang.String"/>
</form-bean>
</form-beans>
<global-forwards type="org.apache.struts.action.ActionForward">
<forward name="welcome" path="/welcome.do"/>
<forward name="searchEntry" path="/searchEntry.do"/>
<forward name="searchSubmit" path="/searchSubmit.do"/>
</global-forwards>
<action-mappings>
<action path="/welcome" forward="/WEB-INF/pages/welcome.htm"/>
<action path="/searchEntry" forward="/WEB-INF/pages/search.jsp"/>
<action path="/searchSubmit"
type="org.springframework.web.struts.DelegatingActionProxy" |(1)
input="/searchEntry.do"
validate="true"
name="searchForm">
<forward name="success" path="/WEB-INF/pages/detail.jsp"/>
<forward name="failure" path="/WEB-INF/pages/search.jsp"/>
</action>
</action-mappings>
<message-resources parameter="ApplicationResources"/>
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/beans.xml"/>
</plug-in>
</struts-config>
|
清单 5 是一个典型的 struts-config.xml 文件,只有一个小小的差别。它注册 Spring 代理类的名称,而不是声明动作的类名,如(1)处所示。DelegatingActionProxy 类使用动作映射名称查找 Spring 环境中的动作。这就是我们使用 ContextLoaderPlugIn
声明的环境。
将一个 Struts 动作注册为一个 Spring bean 是非常直观的,如清单 6 所示。我利用动作映射使用 <bean>
标记的名称属性(在这个例子中是 "/searchSubmit
")简单地创建了一个 bean。这个动作的 JavaBean 属性像任何 Spring bean 一样被填充:
清单 6. 在 Spring 环境中注册一个 Struts 动作
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/> <bean name="/searchSubmit" class="ca.nexcel.books.actions.SearchSubmit"> <property name="bookService"> <ref bean="bookService"/> </property> </bean> </beans> |
|
|
动作委托解决方法是这三种方法中最好的。Struts 动作不了解 Spring,不对代码作任何改变就可用于非 Spring 应用程序中。RequestProcessor
的改变不会影响它,并且它可以利用 Spring AOP 特性的优点。
动作委托的优点不止如此。一旦让 Spring 控制您的 Struts 动作,您就可以使用 Spring 给动作补充更强的活力。例如,没有 Spring 的话,所有的 Struts 动作都必须是线程安全的。如果您设置 <bean>
标记的 singleton 属性为“false”,那么不管用何种方法,您的应用程序都将在每一个请求上有一个新生成的动作对象。您可能不需要这种特性,但是把它放在您的工具箱中也很好。您也可以利用 Spring 的生命周期方法。例如,当实例化 Struts 动作时,<bean>
标记的 init-method 属性被用于运行一个方法。类似地,在从容器中删除 bean 之前,destroy-method 属性执行一个方法。这些方法是管理昂贵对象的好办法,它们以一种与 Servlet 生命周期相同的方式进行管理。
|
|
前面提到过,通过将 Struts 动作委托给 Spring 框架而整合 Struts 和 Spring 的一个主要的优点是:您可以将 Spring 的 AOP 拦截器应用于您的 Struts 动作。通过将 Spring 拦截器应用于 Struts 动作,您可以用最小的代价处理横切关注点。
虽然 Spring 提供很多内置拦截器,但是我将向您展示如何创建自己的拦截器并把它应用于一个 Struts 动作。为了使用拦截器,您需要做三件事:
- 创建拦截器。
- 注册拦截器。
- 声明在何处拦截代码。
这看起来非常简单的几句话却非常强大。例如,在清单 7 中,我为 Struts 动作创建了一个日志记录拦截器。 这个拦截器在每个方法调用之前打印一句话:
清单 7. 一个简单的日志记录拦截器
package ca.nexcel.books.interceptors; import org.springframework.aop.MethodBeforeAdvice; import java.lang.reflect.Method; public class LoggingInterceptor implements MethodBeforeAdvice { public void before(Method method, Object[] objects, Object o) throws Throwable { System.out.println("logging before!"); } } |
这个拦截器非常简单。before()
方法在拦截点中每个方法之前运行。在本例中,它打印出一句话,其实它可以做您想做的任何事。下一步就是在 Spring 配置文件中注册这个拦截器,如清单 8 所示:
清单 8. 在 Spring 配置文件中注册拦截器
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="bookService" class="ca.nexcel.books.business.BookServiceImpl"/> <bean name="/searchSubmit" class="ca.nexcel.books.actions.SearchSubmit"> <property name="bookService"> <ref bean="bookService"/> </property> </bean> <!-- Interceptors --> <bean name="logger" class="ca.nexcel.books.interceptors.LoggingInterceptor"/> |(1) <!-- AutoProxies --> <bean name="loggingAutoProxy" class="org.springframework.aop.framework.autoproxy. BeanNameAutoProxyCreator"> |(2) <property name="beanNames"> <value>/searchSubmit</valuesgt; |(3) </property> <property name="interceptorNames"> <list> <value>logger</value> |(4) </list> </property> </bean> </beans> |
您可能已经注意到了,清单 8 扩展了 清单 6 中所示的应用程序以包含一个拦截器。具体细节如下:
- 在 (1) 处,我注册了这个拦截器。
- 在 (2) 处,我创建了一个 bean 名称自动代理,它描述如何应用拦截器。还有其他的方法定义拦截点,但是这种方法常见而简便。
- 在 (3) 处,我将 Struts 动作注册为将被拦截的 bean。如果您想要拦截其他的 Struts 动作,则只需要在 "beanNames" 下面创建附加的
<value>
标记。 - 在 (4) 处,当拦截发生时,我执行了在 (1) 处创建的拦截器 bean 的名称。这里列出的所有拦截器都应用于“beanNames”。
就是这样。就像这个例子所展示的,将您的 Struts 动作置于 Spring 框架的控制之下,为处理您的 Struts 应用程序提供了一系列全新的选择。在本例中,使用动作委托可以轻松地利用 Spring 拦截器提高 Struts 应用程序中的日志记录能力。
|
|
在本文中,您已经学习了将 Struts 动作整合到 Spring 框架中的三种窍门。使用 Spring 的 ActionSupport
来整合 Struts(第一种窍门中就是这样做的)简单而快捷,但是会将 Struts 动作与 Spring 框架耦合在一起。如果您需要将应用程序移植到一个不同的框架,则需要重写代码。第二种解决方法通过委托 RequestProcessor
巧妙地解开代码的耦合,但是它的可扩展性不强,并且当 Struts 的 RequestProcessor
变成一系列命令时,这种方法就持续不了很长时间。第三种方法是这三种方法中最好的:将 Struts 动作委托给 Spring 框架可以使代码解耦,从而使您可以在您的 Struts 应用程序中利用 Spring 的特性(比如日志记录拦截器)。
三种 Struts-Spring 整合窍门中的每一种都被实现成一个完整可用的应用程序。请参阅 下载 部分仔细研究它们。
|
|
j-sr2-actionsupport.zip | 5 MB | HTTP |
j-sr2-requestprocessor.zip | 5 MB | HTTP |
j-sr2-delegate.zip | 5 MB | HTTP |
关于下载方法的信息 |
学习
-
Spring 系列(Naveen Balani,developerWorks,2005 年 6 到 9 月):对 Spring 框架的组件和特性(包括 Spring AOP)的分为四部分的介绍。
-
Best practices in Struts development(Palaniyappan Thiagarajan 和 Pagadala Suresh,developerWorks,2004 年 6 月):概述了 Struts
Action
组件。
-
Inversion of Control Containers and the Dependency Injection pattern(Martin Fowler,2004 年 1 月):介绍 IOC 容器。
-
Introduction to the Spring Framework(Rod Johnson,The ServerSide,2005 年 5 月):Spring 的创立者解释了为什么 Spring 框架很重要。
-
Struts Recipes(George Franciscus 和 Danilo Gurovich;Manning,2004 年):关于 Struts 窍门和最佳实践的一个流行的纲要。
-
Struts In Action(Ted Husted、Cedric Dumoulin、George Franciscus、David Winterfeldt;Manning,2002 年):针对专业 Struts 开发人员的综合资源。
-
Spring In Action(Craig Walls 和 Ryan Breidenbach;Manning,2005 年):一本用于开发人员的 Spring 资源书籍。
-
Java 技术专区:找到关于 Java 编程各个方面的文章。
获得产品和技术
讨论
-
参与论坛讨论。
- developerWorks blogs:加入 developerWorks 社区。
George Franciscus 是 Java 公司的一名顾问和 Struts 方面的权威。他是 Manning 出版的 Struts Recipes 和 Struts in Action 的合著者。 George 通过 nexcel.ca 提供有关技术和管理方面的咨询服务。 |
相关推荐
基于模拟退火算法与A*算法融合的送餐机器人多目标点路径规划策略,多目标点路径规划---模拟 火算法+A*算法 送餐机器人多目标点路径规划,室内AGV路径规划。 基于模拟 火算法融合A*算法的移动机器人路径规划 1,从厨房出发,移动到多个目标点,最后返回厨房。 2,采用A*算法规划两点间的距离,然后依据规划路径距离模拟 火算法运算全过程最短距离。 旅行商的室内规划应用 ,多目标点路径规划; 模拟退火算法; A*算法; 送餐机器人; 室内AGV路径规划; 移动机器人路径规划; 厨房出发; 最短距离; 旅行商应用。,基于模拟退火算法与A*算法融合的送餐机器人多目标点路径规划系统
"谐波抑制Matlab Simulink仿真实践:有源无源混合型(PPF、APF)滤波效果对比报告",谐波抑制matlab simulink仿真,包含有源无源混合(ppf、apf,混合型)效果好可参考,有报告,下图为ppf滤波前后对比 ,谐波抑制; MATLAB Simulink仿真; 有源无源混合滤波; PPF与APF混合型; 滤波效果; 报告对比,Matlab Simulink仿真:混合型谐波抑制技术报告
线上一流课程教学辅助系统 免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1jKDjYrEz1 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
沉浸式戏曲文化体验系统 免费JAVA毕业设计 2024成品源码+论文+录屏+启动教程 启动教程:https://www.bilibili.com/video/BV1jKDjYrEz1 项目讲解视频:https://www.bilibili.com/video/BV1Tb421n72S 二次开发教程:https://www.bilibili.com/video/BV18i421i7Dx
基于Matlab GUI界面的工件尺寸测量系统:数字图像处理技术在机械零件测量中的应用,- 标题:基于Matlab的工件测量系统 - 关键词:matlab GUI界面 工件尺寸测量 圆 长方形 直径 周长 数字图像处理 - 步骤:打开图像 选择标签 灰度化 滤波(中值,均值,高斯) 二值化 边缘检测 尺寸测量 结果绘制在在GUI上 - 简述:使用matlab数字图像处理技术,处理锯片,垫片,螺丝等机械零件的尺寸,只要包含半径(内径和外径),周长,长宽等,并在原图上进行绘制,并展示在界面上。 ,Matlab; GUI界面; 图像处理; 尺寸测量; 圆; 长方形; 半径; 周长; 边缘检测; 机械零件,"基于Matlab GUI界面的工件尺寸测量系统"
FDTD COMSOL技术下的超结构与超表面光吸收与分光滤波模型:一维至三维SPP偏振模型的自研与文献参考,FDTD COMSOL现有MIM超结构模型,超表面超吸收分光滤波SPP模型(一维光栅,二维光栅,三维超表面,偏振模型),介质超表面BIC模型等都是自己做的,文献参考, ,关键词:FDTD;COMSOL;MIM超结构模型;超表面超吸收分光滤波SPP模型;一维光栅;二维光栅;三维超表面;偏振模型;介质超表面BIC模型;文献参考,自研MIM超结构及多类超表面光学模型集
"金豺优化算法在冷热电联供系统优化调度中的应用:基于MATLAB平台的仿真与实证研究",金豺优化算法(2022年)冷热电联优化调度 说明书MATLAB代码:基于金豺优化算法冷热电联优化调度 关键词: 冷热电三联供 金豺优化算法 仿真平台:MATLAB 平台采用金豺优化算法实现求解优势:代码注释详实,适合参考学习,程序非常精品,请仔细辨识 主要内容:代码构建了含冷、热、电负荷的冷热电联供型系统优化调度模型,考虑了各出力源出力成本及环境污染治理成本、分时电价,考虑了光伏、风机、燃气轮机、燃料电池、电制冷机、电锅炉、余热回收以及蓄电池、蓄热装置、蓄冷装置等资源,并且考虑与上级电网的购电,考虑了燃机出力的非线性,实现CCHP系统的经济运行,求解效果极佳,具体可以看图 ,冷热电三联供;金豺优化算法;MATLAB平台;系统优化调度模型;资源利用;经济运行;求解效果极佳;CCHP系统;非线性问题;详实注释。,《基于金豺优化算法的冷热电联供系统MATLAB仿真优化调度说明书》
,永磁同步电机伺服控制仿真三环PI参数自整定 Matlab仿真模型 1.模型简介 模型为永磁同步电机伺服控制仿真,采用 Matlab R2018a Simulink搭建。 模型内主要包含DC直流电压源、三相逆变器、永磁同步电机、采样模块、SVPWM、Clark、Park、Ipark、位置环、速度环、电流环等模块,其中,SVPWM、Clark、Park、Ipark模块采用Matlab funtion编写,其与C语言编程较为接近,容易进行实物移植。 模型均采用离散化仿真,其效果更接近实际数字控制系统。 2.算法简介 伺服控制由位置环、速度环、电流环三环结构构成,其中,电流环采用PI控制,并具有电流环解耦功能;转速环采用抗积分饱和PI控制;位置环采用P+前馈的复合控制,能够更好地跟踪指令信号。 本仿真中最大的亮点是三环PI参数自整定,只需输入正确的电机参数(电阻、电感、转动惯量等参数),无需手动调节PI参数,能够节省调试时间。 3.仿真效果 位置响应波形,如下图所示。 转速响应波形,如下图所示。 转矩电流响应波形,如下图所示。 4. 可提供模型
基于西门子PLC与组态王技术的锅炉控制系统设计与应用,13基于西门子PLC和组态王锅炉控制系统 ,基于西门子PLC; 锅炉控制系统; 组态王; 自动化控制,基于西门子PLC与组态王锅炉控制系统研究
转子动力学与模态分析:临界转速计算与稳定状态下的轴心轨迹分析,圆盘质量不平衡条件下的振动响应及操作视频解析。,转子动力学,模态分析求临界转速,稳定状态下转子轴心轨迹,圆盘质量不平衡条件下振动响应+操作视频。 ,转子动力学;模态分析;临界转速;稳定状态;轴心轨迹;质量不平衡;振动响应;操作视频。,转子动力学分析:模态与振动响应研究视频
一阶直线倒立摆非线性动力学模型的MATLAB Simulink仿真研究:模型推导、S-Function实现与离散PID控制的测试服务,一阶直线倒立摆MATLAB Simulink仿真 (1)模型推导 + 仿真工程 (2)讲解服务 主要保留模型的非线性动力学特性,即不在平衡点做线性化处理; (1)MathType 详细推导二阶非线性微分方程 (2)S-Function 实现非线性连续状态空间模型 (3)测试离散PID控制倒立摆重心变化适应性 #倒立摆 #MATLAB #Simulink #离散控制 #S-Function ,一阶直线倒立摆; MATLAB Simulink 仿真; 模型推导与仿真工程; 非线性动力学特性; MathType 推导; S-Function 实现; 离散PID控制; 重心变化适应性。,一阶直线倒立摆非线性动力学MATLAB Simulink仿真研究
基于AHP-CRITIC组合变权与指标劣化度修正的赋权方法研究,38考虑劣化度APH-CRITIC组合变权 组合变权赋权方法,基于AHP和改进CRITIC计算主客观权重,引入指标劣化度构造变权函数对综合权重进行修正,还方法可以捕捉指标时序的劣化程度,实现数据的有效跟踪,评价更加合理。 可根据需求进行改进。 ,关键词:组合变权赋权方法;AHP;CRITIC;指标劣化度;变权函数;时序劣化程度;数据跟踪;评价合理。,基于AHP-CRITIC组合变权法:综合主客观权重与指标劣化度评价
基于两并联虚拟阻抗下垂控制的微电网有功功率共享技术研究及其应用效果分析——有参考文献支撑,微电网,下垂控制,两并联阻抗下垂控制,实现了有功功率共享,效果好,有参考文献。 ,微电网;下垂控制;两并联虚拟阻抗下垂控制;有功功率共享;参考文献,微电网两并联虚拟阻抗下垂控制技术实现有功共享,效果显著,有参考文献支持。
MATLAB仿真湍流相位屏相位结构函数:功率谱反演法及其低频信息补偿优化研究,MATLAB仿真湍流相位屏相位结构函数 功率谱反演法 补偿低频信息达到与理论更好的拟合程度 ,MATLAB仿真; 湍流相位屏; 相位结构函数; 功率谱反演法; 低频信息补偿; 理论拟合,MATLAB仿真湍流相位屏结构与功率谱反演法优化研究
棋盘设计: 创建一个 15x15 的棋盘,用户可以点击每个格子放置棋子。 棋子颜色: 黑方和白方棋子通过 CSS 样式显示为圆形。 胜利检测: 检查横向、纵向和对角线的五子连珠以判断胜利。 游戏重置: 游戏可以重置,重新开始。 重新开始按钮: 点击后重置游戏状态,清空棋盘。 退出游戏按钮: 点击后弹出确认对话框,确认后尝试关闭窗口。
基于f(x,y,z,t)的高斯烟团模型纯Python代码实现:大气稳定度计算、坐标转换与扩散系数分析,三维浓度叠加值的计算研究,基于f(x,y,z,t)的高斯烟团模型纯Python代码实现(包涵大气稳定度计算、坐标转,扩散系数以及三维坐标系内浓度叠加值) ,核心关键词:f(x,y,z,t)高斯烟团模型; 大气稳定度计算; 坐标转换; 扩散系数; 三维坐标系内浓度叠加值; 纯Python代码实现;,Python实现高斯烟团模型的大气扩散浓度计算代码
基于ADRC的主动悬架控制技术:设计观测器与非线性误差反馈控制器的优化研究,基于ADRC的主动悬架控制: 1.设计观测器 2.非线性误差反馈控制器。 相同参数下,优于pid的调节效果。 并且可查看观测器对比被控对象效果模型绝对正确 参考文献(仅用于学术交流) ,基于ADRC的主动悬架控制; 观测器设计; 非线性误差反馈控制器; 调节效果优于PID; 观测器对比被控对象效果模型绝对正确,基于ADRC的主动悬架:观测器设计与非线性误差反馈控制
matlab实现CNN时序预测完整程序+数据
基于视频分析的地 震检测.pdf
烟花代码编程python满屏。编程实现python代码烟花满屏燃放效果。这是一个用 Python 和 Pygame 实现烟花满屏燃放效果的代码,通过定义 Firework 和 Particle 类,模拟烟花的上升和爆炸过程。烟花从屏幕底部随机位置升起,达到一定高度后爆炸,生成大量彩色粒子向四周扩散。粒子具有随机的速度、颜色和生命周期,随着时间逐渐消失。