The @Install
annotation lets you control conditional installation of components that are required in some deployment scenarios and not in others. This is useful if:
-
You want to mock out some infrastructural component in tests.
-
You want change the implementation of a component in certain deployment scenarios.
-
You want to install some components only if their dependencies are available (useful for framework authors).
@Install
works by letting you specify
precedence
and
dependencies
.
The precedence of a component is a number that Seam uses to decide which component to install when there are multiple classes with the same component name in the classpath. Seam will choose the component with the higher precendence. There are some predefined precedence values (in ascending order):
-
BUILT_IN
— the lowest precedece components are the components built in to Seam.
-
FRAMEWORK
— components defined by third-party frameworks may override built-in components, but are overridden by application components.
-
APPLICATION
— the default precedence. This is appropriate for most application components.
-
DEPLOYMENT
— for application components which are deployment-specific.
-
MOCK
— for mock objects used in testing.
Suppose we have a component named messageSender
that talks to a JMS queue.
@Name("messageSender")
public class MessageSender {
public void sendMessage() {
//do something with JMS
}
}
In our unit tests, we don't have a JMS queue available, so we would like to stub out this method. We'll create a
mock
component that exists in the classpath when unit tests are running, but is never deployed with the application:
@Name("messageSender")
@Install(precedence=MOCK)
public class MockMessageSender extends MessageSender {
public void sendMessage() {
//do nothing!
}
}
The precedence
helps Seam decide which version to use when it finds both components in the classpath.
This is nice if we are able to control exactly which classes are in the classpath. But if I'm writing a reusable framework with many dependecies, I don't want to have to break that framework across many jars. I want to be able to decide which components to install depending upon what other components are installed, and upon what classes are available in the classpath. The @Install
annotation also controls this functionality. Seam uses this mechanism internally to enable conditional installation of many of the built-in components. However, you probably won't need to use it in your application.