Skip to content

DependencyInjection

Martin Goellnitz edited this page Dec 8, 2015 · 3 revisions

Dependency Injection

Tangram heavily relies on Dependency Injection for the setup of the application created since it is intended to be a set of building blocks where any reasonable combination should be possible and come with a set of reasonable defaults which then can be customized by the application.

While relying on Dependency Injection as such, Tangram tries to avoid to rely on a specific Dependency Injection implementation but provides glue codes for three solutions. This is achieved by the use of the standard Java JSR330 annotations.

Springframework

Early versions of Tangram where more or less a specific setup of a [Springframework] spring based web application with a data layer not relying on the Springframework and some customized object oriented templating using Springframework views (JSPs in this case).

This has completely changed and the Springframework is just one of the options removing most of the specific codes and leaving just a minimal set of these codes as a Tangram module. So when using the Springframework, you have to add the dependency tangram:tangram-spring to our project.

The Springframework is not only responsible for the setup of your application' components through Dependency Injection but also handles the controller and the view part of the application. The model elements from the Springframework are not used by Tangram, other elements are optional and the use is completely your decision.

When using the Springframework together with Tangram you are still free to use the Controller part, the Interceptors, and the like from the Springframework directly and don't need to use the Tangram specific elements like LinkHandlers.

Setup

Typical though minimal web.xml for the use of Tangram together with the Springframework:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

  <display-name>Tangram JPA Example using OpenJPA, EclipseLink, Hibernate, or DataNucleus - Springframework version</display-name>

  <!-- the tangram servlet, everything except static files is handled here -->
  <servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.tangram.spring.TangramServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
      classpath*:tangram/*.xml,
      /WEB-INF/tangram/*.xml
      </param-value>
    </init-param>
  </servlet>
  <servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/s/*</url-pattern>
  </servlet-mapping>

  <!-- you will definetely want this! -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- example of static expiration rules depending on extensions -->
  <filter>
    <filter-name>expiryFilter</filter-name>
    <filter-class>org.tangram.util.ExpirationHeaderFilter</filter-class>
    <init-param>
      <param-name>expirations</param-name>
      <param-value>css=604800,js=604800,ico=604800,gif=604800,html=0,DEFAULT=86400</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>expiryFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <!-- just to say hello and have a redirect to the root of the tangram servlet -->
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

</web-app>

As you can see from the example, you are expected to provide XML configuration elements and properties files to be automatically detected in a "tangram" folder of the resources and in the WEB-INF/tangram folder of the web application. You may add application specific additional paths but may not leave these two paths out, since the Tangram defaults and minimum configurations are provided in thes locations.

application.xml configuration file example:

<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">

  <util:set id="loginProviders" value-type="java.lang.String">
    <value>form</value>
    <value>basic</value>
    <value>yahoo</value>
  </util:set>

  <!-- to make the whole application login protected this will be the list of read capable persons
  <util:set id="allowedUsers" value-type="java.lang.String">
    <value>form:user</value>
  </util:set>
  -->

  <util:set id="adminUsers" value-type="java.lang.String">
    <value>form:admin</value>
  </util:set>

  <util:map id="usernamePasswordMapping" key-type="java.lang.String" value-type="java.lang.String">
    <entry key="user" value="04f8996da763b7a969b1028ee3007569eaf3a635486ddab211d512c85b9df8fb" />
    <entry key="admin" value="8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918" />
  </util:map>

  <!-- Example additional login client -->
  <bean id="yahooLogin" class="org.pac4j.openid.client.YahooOpenIdClient">
    <property name="name" value="yahoo"/>
  </bean>

  <bean id="jdoConfigOverrides" class="java.util.HashMap">
    <constructor-arg>
      <map>
        <entry key="javax.jdo.option.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
        <entry key="javax.jdo.option.ConnectionURL" value="jdbc:hsqldb:file:db/hsqldb/tangram"/>
        <entry key="javax.jdo.option.ConnectionUserName" value="sa"/>
        <entry key="javax.jdo.option.ConnectionPassword" value=""/>
        <entry key="javax.jdo.option.Mapping" value="hsqldb"/>
      </map>
    </constructor-arg>
  </bean>

</beans>

Springframework specific properties to be used in automatically included xml configuration files:

# Can be changed in web.xml and must be the same value here
tangram.servlet.path=/s
# use as deep as possible to make component scan on startup short
bean.factory.application.base.package=org.tangram.example
# only fiddle around with this in cases of problems with content updates
bean.factory.activate.caching=true
# resource name in the app jar to invalidate cache if the app changes
tangram.restart.cache.marker=org/tangram/example

Google Guice with Guicy

Unlike the other options for application setup using Dependecy Injection with Tangram, the Google Guice implementation is not just about using the means provided by Google Guice to define beans and inject values. To be able to provide the same level of reasonable defaults and means to override them, the Guice integration had to be extended.

Dinistiq

Although Dinistiq is a very simply Dependency Injection library, Tangram can be used in conjunction with it without any limitations.

Setup

In the resource tree of your application you need a dinistiq and a dinistiq/beans subfolder. In the dinistiq folder you will place one or more properties files to manually set up some components there.

Example properties file to setup java beans in the dinistiq scope:

loginProviders=java.util.Set(form,yahoo)
yahooLogin=org.pac4j.openid.client.YahooOpenIdClient

adminUsers=java.util.Set(form:admin,basic:admin)
allowedUsers=java.util.HashSet
freeUrls=java.util.Set(/s/stats,/s/login,/s/callback,/s/redirect/form,/s/redirect/yahoo,/s/redirect/twitter,/s/login-form)

In the beans folders, you can place properties files named after their respective bean to set up any optional or overridden values. In the above example, the yahooLogin is missing its name to correspond with the loginProviders set.

dinistiq/yahooLogin.properties:

name=yahoo

Also beans set up by the Tangram base framework may be customized here, like - say - the database access or the packages where the data model can be found.

dinistiq/jdoConfigOverrides.properties:

# hsqldb config example.
javax.jdo.option.ConnectionDriverName=org.hsqldb.jdbcDriver
javax.jdo.option.ConnectionURL=jdbc:hsqldb:file:db/hsqldb/tangram
javax.jdo.option.ConnectionUserName=sa
javax.jdo.option.ConnectionPassword=
javax.jdo.option.Mapping=hsqldb

dinistiq/beanFactory.properties:

basePackages=org.tangram.example,org.tangram.nucleus
Clone this wiki locally