![]() |
| |||||||||||||||||||
| Resin 3.1 Documentation Examples Changes Overview Installation Configuration Quercus SOA/IoC JSP Servlets and Filters Admin (JMX) EJB Amber Security Performance Hessian XML and XSLT Third-party Troubleshooting/FAQ Command-Line Options Tags Common Tasks Relax Schema howto Config FAQ Scrapbook DB Scrapbook Resin IoC Virtual Hosting Database Load Balancing Sessions Clustered Sessions Tuning ISP WebApp Deploy |
Resin's dependency injection framework gives your application a type-safe architecture for designing and assembling services and components. Since injection is annotation-based, most components can avoid XML configuration, while XML is still available for components. Injecting ResourcesBefore dependency injection, applications needed to use JNDI to
grab resources managed by Resin: database connections, JMS queues, JCA
With dependency injection, Resin will lookup, verify and inject
the resource when it creates your managed class, for example when creating
a servlet. In the following example, when Resin creates MyServlet, the
import javax.sql.DataSource;
import javax.transaction.UserTransaction;
import javax.webbeans.In;
public class MyServlet extends GenericServlet {
@In private DataSource _ds;
@In private UserTransaction _ut;
...
}
@Named and bindingsSince many applications use multiple resources like named databases,
your injection may need to specify a name or other binding to uniquely
identify the resource you want. In the case of a unique resource like
import javax.sql.DataSource;
import javax.webbeans.Named;
public class MyServlet extends GenericServlet {
@Named("foo") private DataSource _ds;
...
}
<web-app xmlns="http://caucho.com/ns/resin">
<database>
<name>foo</name>
<driver type="org.gjt.mm.mysql.Driver">
<url>jdbc:mysql://localhost:3306/foo</url>
</driver>
</database>
<database>
<name>bar</name>
<driver type="org.gjt.mm.mysql.Driver">
<url>jdbc:mysql://localhost:3306/bar</url>
</driver>
</database>
</web-app>
Injection using a Although many applications will just use field, method, and constructor injectionSince Resin implements all three flavors of dependency injection: field, method and constructor, the choice of style is up to you. You can mark any field with
import javax.webbeans.Named;
public class MyBean {
@Named DataSource _ds;
...
}
Method injection can use any binding annotation on any of the parameters.
When Resin introspects the component class and it finds
any
import javax.webbeans.Named;
public class MyBean {
void foo(@Named("jdbc/foo") DataSource myDataSource) { ... }
...
}
Construction injection is available for components and singleton beans.
Like method injection, the If the bean has multiple constructors, exactly one must be marked
import javax.webbeans.In;
public class MyBean {
@In
public MyBean(DataSource myDataSource) { ... }
...
}
WebBeans-enabled components (injectable objects)Any Resin-managed object can use the entire WebBeans
dependency-injection system and all of the managed objects, while objects
you create using
Resin global resourcesResin automatically provides several global resources to any
injectable code. Since these resources are unique, your application
will use
Resin configured resourcesAll Resin configured resources are available through WebBeans, since Resin uses WebBeans as its internal registry.
EJB stateless beans are automatically registered the
WebBeans. The default EJB stateful beans are automatically registered with
WebBeans. The default EntityManager and EntityManagerFactory objects
from JPA are automatically registered with WebBeans. The default
<env-entry> tags register their values with
WebBeans. The default <jms-connection-factory> automatically registers the configured
factory with WebBeans.
Connection factories can also be configured with <bean> or <resource>,
depending on the JMS provider. The registered type is the <jms-topic> automatically registers the configured
topic with WebBeans. The default <jms-queue> automatically registers the configured
queue with WebBeans. The default <resource> automatically registers the configured resource with WebBeans. In the future, the resource tag will likely be replaced by <bean> instances. The registered type is the resource type. <web-service-client> registers remoting clients with WebBeans.
The <web-service-client> tag will configure the protocol used and the
expected proxy class. The registered type is the API
<web-app xmlns="http://caucho.com/ns/resin">
<web-service-client class="example.HelloService">
<url>hessian:http://localhost:8080/hello/</url>
</web-service-client>
</web-app>
public class MyServlet extends GenericServlet {
@In example.HelloService _hello;
...
}
Application componentsThe primary value of Resin's dependency injection system is as a type-safe component and service organization registry. Module and component-oriented software has been a goal of software developers for decades, but in practice developing components and services is a difficult task, in large part because the configuration and assembly of the components has been just as complicated as the code itself. There are no silver bullets in software, but the WebBeans registry does significatly reduce the housekeeping code and XML which gets in the way of good design. Annotation-based Component DiscoveryAt startup, Resin will scan jars and class directories for a
<web-beans xmlns="http://caucho.com/ns/resin"> </web-beans> The component itself can be any Java class. Since Resin manages the
component, it can use
import javax.annotation.PostConstruct;
import javax.webbeans.Component;
@Component
public class Movie {
private String _title;
private String _director;
public String getTitle() { return _title; }
public void setTitle(String title) { _title = _title; }
public String getDirector() { return _director; }
public void setDirector(String director) { _director = director; }
@PostConstruct
public void init()
{
...
}
}
The Any other component or Resin-managed class like servlets can now
use
import javax.webbeans.In;
public class MyServlet extends GenericServlet {
@In Movie _movie;
...
}
Most application components will use the Scopes: @Singleton, @Dependent, @RequestScopedThe scope of the component determines when Resin will create a new component and when it will reuse an old one. Singletons will always return the same object, while dependent components will always return a new object instance. Long-lived services will typically be singletons, while scratch-space modules will be dependent components. Components default to You can specify a component's scope with an annotation or in
the
An example scoped resource might be a
import javax.webbeans.RequestScoped;
import javax.webbeans.Component;
@RequestScoped
@Component
public class Calculator {
private int _a;
private int _b;
public void setA(int a) { _a = a; }
public void setB(int b) { _b = b; }
public int getSum() { return _a + _b; }
}
You could also register the same calculator using XML: <web-app xmlns="http://caucho.com/ns/resin"> <component class="example.Calculator" scope="request"/> </web-app> @New Component DiscoveryThe
import javax.webbeans.New;
public class MyServlet extends GenericServlet {
@New Movie _movie;
...
}
The
public class Movie {
private String _title;
public String getTitle() { return _title; }
public void setTitle(String title) { _title = title; }
@PostConstruct
public void init() { ... }
}
XML configuration overviewYou can register your components and services with Resin using the resin.conf or resin-web.xml files. Since the WebBeans registry is integrated with Resin, your services be treated as first-class components along with the Resin resources. Although most components will not need XML, there are a few advantages for the small number of services which do use XML. The XML-configuration lets you customize your application for a
particular environment, e.g. setting configuration parameters. For example,
Resin's In addition, the XML-configuration documents the services you've enabled. For heavyweight services, this documentation is critical, while lightweight components do not need this extra housekeeping overhead. bean and component registrationThe <web-app xmlns="http://caucho.com/ns/resin"> <bean class="example.MyService"/> <component class="example.MyService"/> </web-app> The
bean custom XML configurationResin's XML configuration uses the standard JavaBeans patterns to configure properties. Resin uses the same mechanism for all of its own configuration parsing, including every JavaEE configuration file, the resin-web.xml and the resin.conf itself. So your application will have all the configuration flexibility it needs. Since the component beans can use WebBeans
injections, injected components are typically not configured in
the resin-web.conf, avoiding the need for tags like
public class Hello {
private String _greeting = "default";
public void setGreeting(String greeting) { _greeting = greeting; }
public String getGreeting() { return _greeting; }
}
The basic example sets a
<web-app xmlns="http://caucho.com/ns/resin">
<bean class="example.Hello">
<init>
<greeting>Hello, World</greeting>
</init>
</bean>
</web-app>
Resin's configuration uses 5 basic bean patterns, extending the JavaBeans
conventions. It can configure literal values like string and integers as
well as configuring other beans. Any component bean configured by Resin
has full access to (Currently the patterns are name-based like JavaBeans, since Resin was designed before annotations. We may add configuration annotations in the future. public void setFoo(String data); public void setFoo(Movie data); public void addFoo(Movie data); public Movie createFoo(); public void setText(String data);
As mentioned above, Resin uses these 5 patterns to handle all of the
JavaEE configuration files. In particular, the
<web-app xmlns="http://caucho.com/ns/resin">
<bean class="example.Theater">
<init>
<name>Balboa</name>
<movie title="The Princess Bride"/>
<movie title="The Maltese Falcon"/>
</init>
</bean>
</web-app>
In this example, the
public class Theater {
String _name;
ArrayList<Movie> _movies = new ArrayList<Movie>();
public void setName(String name) { _name = name; }
public Movie createMovie()
{
return new Movie(this);
}
public void addMovie(Movie movie)
{
_movies.add(movie);
}
public static class Movie {
private Theater _theater;
private String _title;
Movie(Theater theater)
{
_theater = theater;
}
public void setTitle(String title) { _title = title; }
}
}
Lifecycle: @PostConstruct and @PreDestroyIf your service needs to initialize itself after being configured, it
can annotation an initialization method with At the end of a component's lifetime, you might need to close some
resources, e.g. closing a socket or delisting from a timer service. Resin
will call any component method marked with For example, a
import javax.annotation.PostConstruct;
import javax.webbeans.In;
import javax.webbeans.Component;
import java.util.concurrent.ScheduledExecutorService;
import com.caucho.webbeans.Singleton;
@Component
@Singleton
public class TimerService {
@In ScheduledExecutorService _timer;
@PostConstruct
public void init()
{
_timerFuture = _timer.scheduleAtFixedRate(this, 0, 2, TimeUnit.SECONDS);
}
...
@PreDestroy
public void close()
{
_timerFuture.cancel(false);
}
}
Scripting: PHP, JSF and JSPIf your application is using a scripting language like PHP for the presentation layer, the WebBeans registry provides a simple interface to use your components and services. Although WebBeans injection is typed, each WebBean is also registered under its name for scripting applications. The name must be globally unique, of course, unlike the typed injection binding. The default scripting name is the name of the component's class, with
the first character lowercased. You can change the name by adding
a
@Component
@RequestScoped
public class Movie {
...
}
Quercus/PHPIn Quercus/PHP, the
<?php
$movie = java_bean("movie");
echo "title: " . $movie->title . "\n";
?>
JSP/JSF ELResin automatically provides the WebBeans variables to EL expressions for both JSP and JSF.
<c:out value="${movie.title}"/>
The JSF also uses the expression language, but uses the deferred syntax, since JSF needs to build a component tree first.
<f:view>
<h:outputText value="#{movie.title}"/>
</f:view>
@BindingType: custom injection bindingAlthough many applications will just use
import com.foo.webbeans.ReadOnly;
import com.foo.webbeans.XA;
public class MyServlet extends GenericServlet {
@ReadOnly DataSource _readDatabase;
@XA DataSource _xaDatabase;
...
}
You can create a custom binding annotation using
the The annotation can also have annotation parameters. If they exist, Resin will make sure only matching components will be injected. The custom binding annotation can be used anywhere predefined binding annotations can, including fields, methods, constructor, producers, or event observers.
package com.foo.webbeans;
@BindingType
@Target({TYPE, METHOD, FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface ReadOnly {
}
@Produces methodsSome components are more easily produced using a factory method rather
than getting instantiated directly. In those cases, your application
can mark a factory component's method with the
import javax.webbeans.Component;
import javax.webbeans.Produces;
import com.caucho.webbeans.Singleton;
@Component
@Singleton
public class MyFactory {
@Produces public List<Movie> currentMovies()
{
...
}
The produces method can be marked with AOP/Method InterceptionSome functions like security, logging and transaction handing need to be used for each method invidually, but require a common implementation pattern. The WebBeans AOP use use a single method as a interceptor for each method invocation. Your method will use an
import com.foo.webbeans.Secure;
@Component
public class MyBean {
@Secure
public void doSomethingSafely() { ... }
}
The implementation class will use the
import javax.interceptor.*;
import javax.webbeans.Interceptor;
@Secure @Interceptor
public class MySecureInterceptor {
@AroundInvoke
public Object checkSecurity(InvocationContext inv) throws Exception
{
if (! myContextIsSecure())
throw new MySecurityException("permissiong denied");
return inv.proceed();
}
}
The interceptors must be enabled in the
<web-beans xmlns="http://caucho.com/ns/resin">
<interceptors>
<interceptor>com.foo.MySecureInterceptor</interceptor>
</interceptors>
</web-beans>
Event HandlingYour components can also handle events thrown through the WebBeans API.
Any method with an
import javax.webbeans.Component;
import javax.webbeans.Observes;
@Component
public class MyHandler {
public void myHandlerMethod(@Observes Movie movie)
{
...
}
}
Your application can throw events through the WebBeans
import javax.webbeans.Container;
public void MyServlet extends GenericServlet {
@In Container _webbeans;
public void service(ServletRequest req, ServletResponse res)
{
_webbeans.raiseEvent(new Movie("A Bridge Too Far"));
}
}
For the above example, Resin will look for all components which
have an
| |||||||||||||||||||