Давно задумывал написать что-то полезное для блоггеров и вконце-концов родилась идея конечно же социальной сети. Да, да, можете ругать за очередной велосипед, но как говорится у своего велосипеда колеса круглее. Собственно вопрос на чем реализовывать особо не стоял, т.к. решено было реализовывать на Java, заодно и получить опыт проектирования с нуля пусть не очень сложного, но все же J2EE приложения. Единственная проблема, которую я сейчас вижу это проблема последующего развертывания - нужно будет выбрать java-хостинг (скорее всего буржуйский) и как-то залить туда приложение. Впрочем проблему деплоя на виртуальный хостинг я еще опишу.
Впрочем выбор Java в качестве платформы для реализации приложения ставит перед нами еще одну проблему выбора - проблему выбора библиотек и фреймворков. Так как я имею опыт работы с Tapestry (не сильно большой, но все же) и этот опыт положительный, для реализации веб-части я выбрал именно данный фреймворк. Tapestry основан на IoC-контейнере Hivemind, но я отказался от его использования в пользу более мощного Spring. Почему Spring, а не например Guice? Потому что Spring позволяет не изобретать велосипед - определение источников данных, подключение Hibernate, AOP, управление транзакциями - это все есть в Spring (точно так же как и возможность определения Generic DAO, интерцепторов и многих других вкусностей). Собственно разобраться со Spring это тоже одна из целей моего проекта.
Так же не маловажную роль сыграл тот факт, что Spring поддерживается Tapestry "из коробки". А вот о том, как подключить Spring к Tapestry и инъектить эти бины на страницы и в компоненты, мы и поговорим.
Для этого необходимо написать фабрику, которая построит контекст Spring'овского веб-приложения. Код данной фабрики может быть следующим:
public class SpringContextFactory {
private ServletContext servletContext;
private WebApplicationContext appContext;
public WebApplicationContext getAppContext() {
return appContext;
}
public ServletContext getServletContext() {
return servletContext;
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
appContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
}
}
private ServletContext servletContext;
private WebApplicationContext appContext;
public WebApplicationContext getAppContext() {
return appContext;
}
public ServletContext getServletContext() {
return servletContext;
}
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
appContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
}
}
Теперь необходимо указать HiveMind'у что данную фабрику можно использовать в качестве SpringContextFactory. Делается это в файле-конфиге HiveMind - /META-INF/hivemodule.xml.
<module id="vposte" version="1.0.0" package="ru.vposte">
<contribution configuration-id="hivemind.ApplicationDefaults">
<default symbol="hivemind.lib.spring-bean-factory" value="service-property:vposte.SpringContextFactory:appContext"/>
</contribution>
<service-point id="SpringContextFactory">
Create WebApplicatonContext for Spring
<invoke-factory>
<construct class="SpringContextFactory">
<set-service property="servletContext" service-id="tapestry.globals.ServletContext"/>
</construct>
</invoke-factory>
</service-point>
</module>
<contribution configuration-id="hivemind.ApplicationDefaults">
<default symbol="hivemind.lib.spring-bean-factory" value="service-property:vposte.SpringContextFactory:appContext"/>
</contribution>
<service-point id="SpringContextFactory">
Create WebApplicatonContext for Spring
<invoke-factory>
<construct class="SpringContextFactory">
<set-service property="servletContext" service-id="tapestry.globals.ServletContext"/>
</construct>
</invoke-factory>
</service-point>
</module>
Здесь vposte. - идентификатор приложения. В случае вашего приложения он может быть изменен.
Ну и конечно же, чтобы Spring работал необходимо прописать Spring'овский ServletContextLoaderListener в web.xml, добавив туда такие строчки:
<servlet-mapping>
<servlet-name>vposte</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet-name>vposte</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-context/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Теперь Spring будет замечательно работать с нашим Tapestry приложением (или наоборот, теперь Tapestry будет фронт-контроллером нашего Spring-приложения).
Для того, чтобы инъектировать Spring-бины на страницы Tapestry необходимо использовать аннотации вида:
@InjectObject("spring:registrService")
public abstract IUserRegistrationService getUserRegistrationService();
public abstract IUserRegistrationService getUserRegistrationService();
Здесь spring - обязательный префикс, который говорит HiveMind'у, что бин нужно грузить из контекста Spring. registrService - название бина, описанное в Spring-контексте (например xml-файлах описания бинов).
Собственно и все, данных шагов вполне достаточно, чтобы использовать всю мощь Spring для создания бизнес-части приложения и красоту и удобство Tapestry для разработки веб-уровня.
З.Ы. вопросы и коментарии как всегда приветствуются.
Системы контроля версий. Git. - замечательная статья об использовании Git для начинающих.
Spring Antipatterns - обсуждение антипаттернов использования Spring в ru_java
Понравилось сообщение - подпишись на блог
Комментариев нет:
Отправить комментарий
Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!