JForum3 Beta 技术架构及具体问题的解决

首先说明的一点,JForum3 Beta确实under heavy development,但功能上都是有的,需要自己做测试,并把所有Bug干掉。

一、技术架构

  • 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);
		}
	}
}

二、具体问题

1.好好看一下Vraptor3.5的文档(http://vraptor.caelum.com.br/en/docs/one-minute-guide/)会节约你很多时间,文档精简的很,没多少。

2.包的问题,用Vraptor3.5里的包,大部分都有了。

3.从Hibernate3.2升级后,有一些小问题要改,最多的是uniqueResult()的结果是Long型,不能再转Integer了。

4.JForumTag里需要自己从springContext里拿Bean:

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

5.页面有些小问题,改改链接就好了,zh_CN.properties里有些字段没有,补齐即可。

6.上传文件大小的问题,Vraptor3.5默认上传文件的大小是两兆,需要重新配置(用代码):

@Component
@ApplicationScoped
public class CustomMultipartConfig extends DefaultMultipartConfig{
    public long getSizeLimit() {
        return 50 * 1024 * 1024; // 50MB
    }
}


你可能感兴趣的:(Vraptor3,JForum3)