重寫了幾個類,使得應用程序更加自由,可以自定義formName,不用綁定pojo名字。
重寫了幾個類,使得應用程序更加自由,可以自定義formName,不用綁定pojo名字。
/**
* Subclasses can override this for custom initialization behavior.
* Gets called by <code>setApplicationContext</code> after setting the context instance.
* <p>Note: Does </i>not</i> get called on reinitialization of the context
* but rather just on first initialization of this object's context reference.
* @throws ApplicationContextException in case of initialization errors
* @throws BeansException if thrown by ApplicationContext methods
* @see #setApplicationContext
*/
protected void initApplicationContext() throws BeansException {
}
愿意為子類可以把初始化bean 動作放入此方法,可以自定義一些動作。
我們再來看看調用
public final void setApplicationContext(ApplicationContext context) throws BeansException {
if (context == null && !isContextRequired()) {
// Reset internal context state.
this.applicationContext = null;
this.messageSourceAccessor = null;
}
else if (this.applicationContext == null) {
// Initialize with passed-in context.
if (!requiredContextClass().isInstance(context)) {
throw new ApplicationContextException(
"Invalid application context: needs to be of type [" + requiredContextClass().getName() + "]");
}
this.applicationContext = context;
this.messageSourceAccessor = new MessageSourceAccessor(context);
initApplicationContext();
}
else {
// Ignore reinitialization if same context passed in.
if (this.applicationContext != context) {
throw new ApplicationContextException(
"Cannot reinitialize with different application context: current one is [" +
this.applicationContext + "], passed-in one is [" + context + "]");
}
}
}
可以看到由 ApplicationObjectSupport 的 setApplicationContext 方法調用
而此方法為 ApplicationContextAware 的唯一接口方法,
public interface ApplicationContextAware {
/**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
此方法被 ApplicationContextAwareProcessor 的 postProcessBeforeInitialization 調用
ApplicationContextAwareProcessor implements BeanPostProcessor
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
return bean;
}
以 BaseCommandController 為例
protected void initApplicationContext() {
if (this.validators != null) {
for (int i = 0; i < this.validators.length; i++) {
if (this.commandClass != null && !this.validators[i].supports(this.commandClass))
throw new IllegalArgumentException("Validator [" + this.validators[i] +
"] does not support command class [" +
this.commandClass.getName() + "]");
}
}
}
子類配置如下
<bean id="addNewsController" class="AddNewsController" scope="request">
<property name="formView" value="/management/news/addNews"/>
<property name="validator" ref="beanValidator"/>
<property name="successView" value="forward:/management/news/newsList.html"/>
<property name="commandClass" value="News"/>
<property name="commandName" value="news"/>
</bean>
public final void setValidator(Validator validator) {
this.validators = new Validator[] {validator};
}
設置Validator數組
在初始化的時候,檢驗 是否支持command 類型
this.validators[i].supports(this.commandClass)
此support 為 org.springframework.validation.Validator 的所有 實現類的 方法,檢驗支持檢驗類的動作。
舉例 配置
<bean id="beanValidator" class="org.springmodules.validation.commons.DefaultBeanValidator">
<property name="validatorFactory" ref="validatorFactory"/>
</bean>
DefaultBeanValidator extends AbstractBeanValidator implements Validator
再看實現方法
/**
* Checks if the validatorFactory is configured to handle this class. Will
* convert the class into a form name, suitable for commons validator.
*
* @return <code>true</code> if the validatorFactory supports the class,
* or <code>false</code> if not
* @see #getFormName(Class)
*/
public boolean supports(Class clazz) {
boolean canSupport = validatorFactory.hasRulesForBean(getFormName(clazz), getLocale());
if (log.isDebugEnabled()) {
log.debug("validatorFactory " + (canSupport ? "does" : "does not")
+ " support class " + clazz + " with form name " + getFormName(clazz));
}
return canSupport;
}
檢驗是否支持輸入類
另一個方法
/**
* If <code>useFullyQualifiedClassName</code> is false (default value), this function returns a
* string containing the uncapitalized, short name for the given class
* (e.g. myBean for the class com.domain.test.MyBean). Otherwise, it returns the value
* returned by <code>Class.getName()</code>.
*
* @param cls <code>Class</code> of the bean to be validated.
* @return the bean name.
*/
protected String getFormName(Class cls) {
return (this.useFullyQualifiedClassName) ? cls.getName() : Introspector.decapitalize(ClassUtils.getShortName(cls));
}
Introspector.decapitalize(ClassUtils.getShortName(cls) 獲得按照西班牙命名法的form 名
這個方法本意是獲得以類名為formName 的所有校驗配置。
實際上有一個重大的設計缺陷
看了一檔第1財經的節目,做的是攜程創始人之一現任CEO 范敏的創業故事。說的是攜程是當初由4位創業者創建的網絡為平臺的旅游訂房公司,從當初的小小企業,到現在在線訂房的龍頭老大。
其中那位CEO說了這句話挺有意思:只有IT和傳統業務完美結合的時候,才能發揮出巨大的能量,從而創業成功。想當初,e龍和中青旅,一個是純IT公司,一個是實力強勁的老牌旅游,攜程能夠從這兩家當中找縫隙絕非易事。如今攜程擁有全國最大的call center 就可以說明這點,IT企業或者傳統企業要想做大,要想創業成功,必須把兩者完美結合起來,淘寶,大眾點評網,等一系列大眾熟知的網站,都能說明這點。光搞IT或者傳統企業沒有好好實行信息化拓展自己的業務的話,是沒有很好的發展的,無數開了關,關了開的IT公司或者其他相類似的企業,都是這樣的。
現在轉到說一碗烏冬面的故事。那位CEO有次去了日本,到一家小店里面吃了碗烏冬面,感到吃了這里的烏冬面后,其他地方都不叫烏冬面,太好吃了。但是看這家店不大,就和店主攀談,為什么不全國連鎖式的開分店呢。店主回答他說,他們家幾代人就是專研烏冬面的,做一件事情就要把它做到最好極致,他們是非常謹慎的開每家分店,只有保證分店的味道100%保證后才能開下一家。
現在講究快節奏,創新的時代,這種精神尤其值得借鑒。仔細想,生活也好,工作也好,創業也好。把一件事情做到尚可,很容易,做到好,又去掉一半人,做到很好,又少一半,到最后,做到極致的人,寥寥無幾。我想,只要自己認準一個目標,堅持到底,把他做到極致。我想也許成功也許會對你打開一道縫隙。
此時此刻,我抱著一塊僅有的木板,在這黑海中浮浮沉沉。
不知道哪里是個頭。
有時候,突然回想,算了,沉了吧,也算掙扎過了,就這么沉了吧。
可人偏偏不死心,不到木板全碎了,是不甘心的。
登錄頁面有很多習慣性的操作,比如打開頁面,焦點在要輸入的文本框;按TAB鍵,光標會按一定的順序切換;輸入完畢,壓下回車等等,你也可以輕松實現,看下面頁面的一個例子:
<HTML>
<HEAD>
<TITLE> 登錄頁面 </TITLE>
<script language="javascript" event="onkeydown" for="document">
<!--
if(event.keyCode==13)
{
document.all('TBUTTON').click();
}
-->
</script>
</HEAD>
<BODY ONLOAD="window.document.forms[0].USERNAME.focus();">
<FORM ACTION="" NAME="TEST" METHOD="POST">
用戶名:<INPUT TYPE="TEXT" NAME="USERNAME" tabindex="1"><BR>
密  碼:<INPUT TYPE="TEXT" NAME="PASSWORD" tabindex="2"><BR>
<INPUT TYPE="BUTTON" NAME="TBUTTON" VALUE="回車" onclick="alert('已經點擊??!');" tabindex="3">
</FORM>
</BODY>
</HTML>
其中腳本部分,是相應回車鍵的,TBUTTON為相應的按鈕名稱;
BODY中ONLOAD為打開頁面時加載操作,在此確定焦點所在,USERNAME為相應的控件名稱;
各個控件中tabindex為TAB順序。
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1342882
Today, I design an e-commerce system data diagram. Beacause of I using hibernate and XDoclet, I use the Class diagram instead of Data structure and ERP diagram. My strategy in J2EE system design is to clear the bussiness logic first, and design POJOs and their relations, finally, implement it with mature 3 or more tier web architecture.
網站favicon完成,網上生成的。使用fw不行。
接下去的任務就是完成基礎CMS系統以及撰寫推廣計劃。
準備推出網站整站設計開發,企業在線形象策劃,企業客戶Royalty管理,企業在線服務推廣等項目。
終于向著理念前進了。
感覺很累,前一陣每天工作到凌晨4點,今天要好好睡覺了。