JForum3 Beta 技術架構及具體問題的解決

首先說明的一點,JForum3 Beta確實under heavy development,但功能上都是有的,須要本身作測試,並把全部Bug幹掉。

1、技術架構

  • MVC框架:Vraptor3.5
  • 依賴注入:Spring 3.0.5
  • 持久化:Hibernate 3.6.10
  • 頁面:jsp+jstl+el-functors+jQuery
  • 全文檢索:Hibernate Search 3.2.0
  • Entities:不是咱們經常使用的POJO,而相似於 業務對象 的概念,實體構造時注入了dao對象。
  • 因爲用了Vraptor,配置文件不多,全是約定。spring配置文件只用來引入SystemGlobals.properties,hibernate配置文件只配了數據庫和映射。Vraptor自己沒有配置文件。
解釋一下Entities這事,JForum3的Entity是這樣的:
@Entity
@Table(name = "jforum_categories")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
@Component
@PrototypeScoped
public class Category implements Serializable {
	@Id
	@SequenceGenerator(name = "sequence", sequenceName = "jforum_categories_seq")
	@GeneratedValue(strategy = GenerationType.AUTO, generator = "sequence")
	@Column(name = "category_id")
	private int id;

	@Column(name = "category_order")
	private int displayOrder;

	@Column(name = "category_moderated")
	private boolean moderated;

	@Column(name = "category_title")
	private String name;

	@Transient
	private CategoryRepository repository;

	public Category() {}

	@Autowired
	public Category(CategoryRepository repository) {
		this.repository = repository;
	}

	public List<Forum> getForums() {
		return this.repository.getForums(this);
	}
        ……
}
  1. 由於實體使用了@Entity註解,因此要有個無參的構造函數給Hibernate反射用。
  2. 由於在頁面上會這麼寫"${category.forums}",經過EL表達式能夠直接從實體對象的方法中拿數據,感受很直接,因此實體裏會有構造函數注入對應的DAO對象CategoryRepository。這與Vraptor有點交相呼應的意思,它的Controller裏面也是構造函數注入所須要的一切。
  3. Vraptor3.5是不能完成2這件事的,由於有一個無參的構造函數,它會忽略掉其餘的構造函數(詳見這裏)。因此用了Spring註解的方式在有參構造函數中注入了CategoryRepository,但這樣出現了兩個SessionFactory,一個是Vraptor的,一個是Spring的。這大概是JForum3最變態的地方了.....
  4. 爲了能讓Hibernate能用上已經注入了對象的Spring的Bean,因此SpringInterceptor橫空出世:
public class SpringInterceptor extends EmptyInterceptor {
	private final SessionFactory sessionFactory;
	private final ApplicationContext beanRegistry;

	public SpringInterceptor(ApplicationContext beanRegistry, SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
		this.beanRegistry = beanRegistry;
	}

	@Override
	public Object instantiate(String entityName, EntityMode entityMode, Serializable id) {
		if (!EntityMode.POJO.equals(entityMode)) {
			return null;
		}

		Class<?> c = getClassByName(entityName);
		Object instance = this.beanRegistry.getBean(c);
		sessionFactory.getClassMetadata(c).setIdentifier(instance, id, EntityMode.POJO);

		return instance;
	}

	private Class<?> getClassByName(String name) {
		try {
			return Class.forName(name);
		} catch (ClassNotFoundException e) {
			throw new ForumException(e);
		}
	}
}

2、具體問題 java

1.好好看一下Vraptor3.5的文檔(http://vraptor.caelum.com.br/en/docs/one-minute-guide/)會節約你不少時間,文檔精簡的很,沒多少。 spring

2.包的問題,用Vraptor3.5裏的包,大部分都有了。 數據庫

3.從Hibernate3.2升級後,有一些小問題要改,最多的是uniqueResult()的結果是Long型,不能再轉Integer了。 session

4.JForumTag裏須要本身從springContext裏拿Bean: 架構

springContext = WebApplicationContextUtils.getRequiredWebApplicationContext(this.pageContext().getServletContext());

5.頁面有些小問題,改改連接就行了,zh_CN.properties裏有些字段沒有,補齊便可。 框架

6.上傳文件大小的問題,Vraptor3.5默認上傳文件的大小是兩兆,須要從新配置(用代碼): jsp

@Component
@ApplicationScoped
public class CustomMultipartConfig extends DefaultMultipartConfig{
    public long getSizeLimit() {
        return 50 * 1024 * 1024; // 50MB
    }
}
相關文章
相關標籤/搜索