程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> Struts2整合Spring從xml到注解

Struts2整合Spring從xml到注解

編輯:關於JSP

struts和spring整合首先要在Web容器啟動的時候自動裝配ApplicationContext的配置信息,可想而知應該在web.xml做相應的配置:
[html]
<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
        classpath:applicationContext.xml 
    </param-value> 
</context-param> 
<listener> 
       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
   </listener> 
配置了org.springframework.web.context.ContextLoaderListener後我們就不惜要編寫代碼顯示地實例化ApplicationContext對象了。至於為什麼要使用監聽是因為web.xml 的加載順序是:context-param -> listener -> filter -> servlet 。如果你是在不想使用監聽,或許你可以嘗試下繼承struts2的org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter重寫這個它的init方法在StrutsPrepareAndExecuteFilter過濾器init中實例化ApplicationContext對象加載配置信息,雖然這種方法也可行,但是當攔截每個action都會加載一次配置信息,重新實例化了一個新的web容器,不僅浪費了資源也讓spring更加依賴了struts。

1、使用xml方式:
struts2配置
<package name="user" extends="struts-default">
<action name="login" class="userAction">
<result name="success">/success.jsp</result>
<result name="input" type="redirect">/index.jsp</result>
</action>
</package>
spring配置
<bean id="userDao" class="org.han.dao.impl.UserDaoImpl" />
<bean id="biz" class="org.han.service.impl.LoginBizImpl">
<property name="userdao" ref="userDao"/>
</bean>

<bean id="userAction" class="org.han.action.LoginAction" scope="prototype" >
<property name="biz" ref="biz" />
</bean>
注意紅色部分,struts2的action class與對應的action bean必須相同,這樣才能由spring管理action;

2、struts2使用零配置方式:
當你導入了零配置插件包的時候千萬要注意約定大於配置,還是上面的spring配置,只是不需要struts2配置了。
第一種方式:只需要將Action的className對應到spring配置中的bean id就行了
@Action(value = "/login", results = { @Result(name = "success", location = "/success.jsp"),@Result(name="input",location="/index.jsp")},className="userAction")
public String login() throws Exception {
// TODO Auto-generated method stub
User u=biz.login(this.getUser());
if(u!=null){
return SUCCESS;
}
return INPUT;
}
第二種方式:
Action注解不需要className了,將spring配置稍作修改
<bean id="org.han.action.LoginAction" class="org.han.action.LoginAction" scope="prototype" >
<property name="biz" ref="biz" />
</bean>
這樣可以是因為當你使用零配置的時候,action的class默認是當前類的全類名,所以和spring整合的時候剛好使用全類名在spring配置中查找以全類名為id的bean。

3、struts2、spring都使用注解方式:
www.2cto.com
<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans 
         http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
         http://www.springframework.org/schema/context 
         http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 
   <context:component-scan base-package="org.han.dao.impl,org.han.service.impl,org.han.action"/> 
</beans> 

<context:component-scan base-package=""/>用此種方式,不需要在配置文件中再配置bean,也不需要再導入上面對應的處理bean。也就是說可以不需要在配置文件中使用<context:annotation-config/>了,因為此種方式會自動導入

[java]
@Namespace("/") 
@Component(value="userLogin") 
@Scope(value="prototype") 
public class LoginAction extends ActionSupport { 
 
    public LoginAction() { 
        super(); 
        // TODO Auto-generated constructor stub 
        System.out.println("action:"+this.hashCode()); 
    } 
     
    @Autowired 
    private ILoginBiz biz; 
    private User user; 
 
    public User getUser() { 
        return user; 
    } 
 
    public void setUser(User user) { 
        this.user = user; 
    } 
    @Autowired 
    public void setBiz(ILoginBiz biz) { 
        this.biz = biz; 
    } 
 
    @Override 
    @Action(value = "hello", results = { @Result(name = "success", location = "/success.jsp"),@Result(name="input",location="/index.jsp")}) 
    public String execute() throws Exception { 
        // TODO Auto-generated method stub 
        System.out.println("biz:"+this.biz.hashCode()); 
        User u=biz.login(this.getUser()); 
        if(u!=null){ 
            return SUCCESS; 
        } 
        return INPUT; 
    } 

@Component 有一個可選的入參,用於指定 Bean 的名稱。一般情況下,Bean 都是 singleton 的,需要注入 Bean 的地方僅需要通過 byType 策略就可以自動注入了,所以大可不必指定 Bean 的名稱。除了提供 @Component 注釋外,還定義了幾個擁有特殊語義的注釋,它們分別是:@Repository、@Service 和 @Controller。在目前的 Spring 版本中,這 3 個注釋和 @Component 是等效的,但是從注釋類的命名上,很容易看出這 3 個注釋分別和持久層、業務層和控制層(Web 層)相對應。雖然目前這 3 個注釋和 @Component 相比沒有什麼新意,但 Spring 將在以後的版本中為它們添加特殊的功能。所以,如果 Web 應用程序采用了經典的三層分層結構的話,最好在持久層、業務層和控制層分別采用 @Repository、@Service 和 @Controller 對分層中的類進行注釋,而用 @Component 對那些比較中立的類進行注釋。

@Scope用於定義Bean的作用范圍。

@Autowired 注釋,它可以對類成員變量、方法及構造函數進行標注,完成自動裝配的工作。當 Spring 容器啟動時,AutowiredAnnotationBeanPostProcessor 將掃描 Spring 容器中所有 Bean,當發現 Bean 中擁有 @Autowired 注釋時就找到和其匹配(默認按類型匹配)的 Bean,並注入到對應的地方中去。所以對成員變量使用 @Autowired 後,您大可將它們的 setter 方法刪除。

@Qualifier(“name”) 中的 name是 Bean 的名稱,所以 @Autowired 和 @Qualifier 結合使用時,自動注入的策略就從 byType 轉變成 byName 了。@Autowired 可以對成員變量、方法以及構造函數進行注釋,而 @Qualifier 的標注對象是成員變量、方法入參、構造函數入參。

@PostConstruct 和 @PreDestroy:JSR-250 為初始化之後/銷毀之前方法的指定定義了兩個注釋類,這兩個注釋只能應用於方法上。標注了 @PostConstruct 注釋的方法將在類實例化後調用,而標注了 @PreDestroy 的方法將在類銷毀之前調用。
通過 <bean> 元素的 init-method/destroy-method 屬性進行配置,都只能為 Bean 指定一個初始化 / 銷毀的方法。但是使用 @PostConstruct 和 @PreDestroy 注釋卻可以指定多個初始化 / 銷毀方法,那些被標注 @PostConstruct 或@PreDestroy 注釋的方法都會在初始化 / 銷毀時被執行。
更多的關於注解使用:請看官方文檔

4、總結:
1、注釋配置不一定在先天上優於 XML 配置。如果 Bean 的依賴關系是固定的,(如 Service 使用了哪幾個 DAO 類),這種配置信息不會在部署時發生調整,那麼注釋配置優於 XML 配置;反之如果這種依賴關系會在部署時發生調整,XML 配置顯然又優於注釋配置,因為注釋是對 Java 源代碼的調整,您需要重新改寫源代碼並重新編譯才可以實施調整。
2、如果 Bean 不是自己編寫的類(如 JdbcTemplate、SessionFactoryBean 等),注釋配置將無法實施,此時 XML 配置是唯一可用的方式。
3、注釋配置往往是類級別的,而 XML 配置則可以表現得更加靈活。比如相比於 @Transaction 事務注釋,使用 aop/tx 命名空間的事務配置更加靈活和簡單。
所以在實現應用中,我們往往需要同時使用注釋配置和 XML 配置,對於類級別且不會發生變動的配置可以優先考慮注釋配置;而對於那些第三方類以及容易發生調整的配置則應優先考慮使用 XML 配置。Spring 會在具體實施 Bean 創建和 Bean 注入之前將這兩種配置方式的元信息融合在一起。

作者:hanzhou4519

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved