3. The following is intended to outline our general product
direction. It is intended for information purposes, and
may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or
functionality, and should not be relied upon in making
purchasing decisions.
The development, release, and timing of any features
or functionality described for Oracle's products remains
at the sole discretion of Oracle.
4. What is JSR 299
JSR-299 defines a unifying dependency injection and
contextual lifecycle model for Java EE 6
• a completely new, richer dependency management model
• designed for use with stateful objects – integrates the “web”
and “transactional” tiers – makes it much easier to build
applications using JSF and EJB together
• includes a complete SPI allowing third-party frameworks to
integrate cleanly in the EE 6 environment
5. What can be injected
• Certain kinds of things pre-defined by the specification:
– (Almost) any Java class
– EJB session beans
– Objects returned by producer methods
– Java EE resources (Datasources, JMS topics/queues, etc)
– Persistence contexts (JPA EntityManager)
– Web service references
– Remote EJBs references
• An SPI allows third-party frameworks to introduce new kinds
of things
6. Simple Example
• A really simple Java class:
public class Greeting {
public String greet(String name) {
return “hello “ + name;
}
}
7. Bean Types
• A Bean type can be almost any Java type
• The example below has 4 bean types
public class Bookshop
extends Business
implements Shop<Book> {
...
}
• Yes 4 ! Bookshop, Business, Shop<Book> and Object...
• Restrict bean types with @Typed annotation
8. Bean Constructor
• Bean constructor are identified with the @Inject
annotation :
public class ShoppingCart {
final private User user;
@Inject
public ShoppingCart(User customer) {
user = customer;
}
}
9. Field Injection
• A simple client:
public class Printer {
@Inject
Greeting greeting;
public void greet() {
System.out.println(
greeting.greet(“world”) );
}
}
10. Constructor Injection
public class Printer {
private final Greeting greeting;
@Inject
public Printer(Greeting greeting) {
this.greeting = greeting;
}
public void greet() {
System.out.println(
greeting.greet(“world”) );
}
}
11. Method Injection
public class Printer {
private Greeting greeting;
@Inject
void init(Greeting greeting) {
this.greeting = greeting;
}
public void greet() {
System.out.println(
greeting.greet(“world”) );
}
}
12. Producer methods
• A producer method acts as a source of objects to be
injected
• Use the @Produces annotation
Public class Shop {
@Produces
PaymentProcessor getPaymentProcessor();
@Produces
List<Product> getProducts();
}
13. Qualifiers
A qualifier is an annotation that lets a client choose
between multiple implementations of a certain type
(class or interface)
• Qualifiers replace lookup via string-based names
• @Default is the default qualifier
14. Defining new Qualifier
To define a new qualifier :
• Write a new annotation
• Annotate it with @Qualifier
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface Informal {}
15. Specifying qualifiers
• On injected field :
@Inject @Informal Greeting greeting;
• In method or constructor parameter
public void setGreeting(@Informal Greeting greeting)
16. Scope and Context
Extensible context model
• A scope type is an annotation
• A context implementation can be associated with the
scope type
Dependent scope, @Dependent
• this is the default
• it means that an object exists to serve exactly one
client, and has the same lifecycle as that client
17. Built-in Scopes
Any web request, web service request, RMI call, EJB
timeout:
• @ApplicationScoped
• @RequestScoped
Any servlet, JSF requests:
• @SessionScoped
• @ConversationScoped
Custom scopes – provided by third-party frameworks
via an SPI
18. Scoped Objects
• A session scoped object
@SessionScoped
public class Login {
private User user;
public void login() {
user = …
}
public User getUser() { return user; }
}
19. Injecting a scoped object
public class Printer {
@Default Greeting greeting;
@SessionScoped Login login;
public void greet() {
System.out.println(
greeting.greet(
login.getUser().getName() ) );
}
}
20. Producing a scoped object
• Annotate the bean with the scope annotation
@SessionScoped
public class Login {
private User user;
@Produces
User getCurrrentUser() {
...
}
}
• Injectable as
@Inject @SessionScoped User user
21. Producing a scoped object
• Annotate the producer with the scope annotation
@RequestScoped
public class Login {
private User user;
@Produces
@SessionScoped
User getCurrrentUser() {
...
}
}
• Injectable as
@Inject @SessionScoped User user
22. Producer fields
Producer fields are just a shortcut:
public class Login {
@Produces
@SessionScoped
User user;
public void login() {
user = ...;
}
}
23. Custom scopes
• Create an annotation for the custom scope
– @Target({TYPE, FIELD, METHOD})
– @Retention(Runtime)
– @Scope or @NormalScope
@Inherited
@NormalScope
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface BusinessProcessScoped
{...}
24. Names
To use our class in Unified EL expressions, give it a name:
@Named(“printer”)
public class Printer {
@Current Greeting greeting;
public void greet() {
System.out.println(
greeting.greet(“world”) );
}
}
25. Unified EL
• Now we can use the object in a JSF or JSP page:
<h:commandButton value=”Say Hello”
action=”#{printer.greet}”/>
<h:outputText value=”#{products.total}”/>
26. Stateful class
If we want our object to hold state, we need to declare the
scope of that state:
@RequestScoped @Named public class Printer {
@Inject Greeting g;
private String name;
public void setName(String name)
{ this.name=name; }
public String getName() { return name; }
public void greet() {
System.out.println(g.greet(name) );
}}
27. Unified EL
• And now we can use it to process a JSF form:
<h:form>
<h:inputText value=”#{printer.name}”/>
<h:commandButton value=”Say Hello”
action=”#{printer.greet}”/>
</h:form>
• Or a JSP :
name : ${printer.name}
28. Events
• Beans may produce and consume events
• Event is :
– A Java object – the event object
– A (possibly empty) set of qualifiers types
public interface Event<T> {
public void fire(T event);
public Event<T> select(Annotation...
qualifiers);
... more select...
}
29. Event producer
• Beans fire event via an Event instance
@Inject
@Admin
Event<LoggedInEvent> loggedInEvent;
• Use the fire() method to send the events
public void login() {
...
loggedInEvent.fire(
new LoggedInEvent(user);
}
30. Observer Method
• Use the @Observes annotation
public void afterLogin(
@Observes LoggedInEvent event) {
....
}
• Or use some qualifiers
public void afterLogin(
@Observes @Admin LoggedInEvent event) {
....
}
31. Interceptor Binding Types
• Interceptors are used to separate cross-cutting concerns
from business logic
• Can be enabled or disabled at runtime
• Interceptor binding type is an annotation annotated with
InterceptorBinding
@Inherited
@InterceptorBinding
@Target({TYPE, METHOD})
@Retention(RUNTIME)
public @interface Transactional {...}
32. Bindings for an interceptor
• Interceptor bindings are specified by annotating the
interceptor class with
– The binding type (here it's @Transactional)
– The Interceptor annotation
@Transactional
@Interceptor
public class TransactionInterceptor {
@AroundInvoke
public Objet manageTx(InvocationContext
ctx) throws Exception {...}
}
33. Binding an interceptor
• Annotate with the interceptor binding type a bean class :
@Transactional
public class ShoppingCart {
// all business methods are
transactional
}
• Or just a method :
Public class ShoppingCart {
@Transactional
public void placeOrder() {...}
}
34. Decorators
• Similar to interceptors but only apply to a particular Java
type.
– Can be easily enabled or disabled at runtime
– Strong semantic binding between the decorator and decorated
public interface Persistence<T> {
void save(T object);
T load();
}
35. Decorator definition
• Annotate with Decorator annotation
@Decorator public class AuthPersistence<T>
implements Persistence<T> {
@Inject @Delegate
Persistence<T> delegate;
public void save(T object) {
authorize();
delegate.save(object);
}
}
36. Stereotypes
• It is not only interceptor bindings we want to reuse!
• We have common architectural “patterns” in our
application, with recurring component roles
– Capture the roles using stereotypes
• A stereotype packages:
– A default scope
– A set of interceptor bindings
– A default scope
– Defaulted bean EL names
38. Using a stereotype
• Annotating a Bean
@Action
public class Greeting {
public String greet(String name) {
return “hello “ + name;
}
}
39. Resources
• To inject Java EE resources, persistence contexts, web
service references, remote EJB references, etc, use a
producer field :
public class UserDatabasePersistenceContext
{
@Produces @UserDatabase
@PersistenceContext
EntityManager userDatabase;
}
40. Resources
• @Resource possible to specify the jndi name
public class PricesTopic {
@Produces @Prices
@Resource(
name=“java:global/env/jms/Prices”)
Topic pricesTopic;
}
41. Injecting resources
• Now we’ve eliminated the use of string-based names:
public class UserDatabasePersistenceContext
{
@UserDatabase
EntityManager userDatabase;
}
public class PricesTopic {
@Prices TopicSession topicSession;
@Prices TopicPublisher topicPublisher;
}
42. More information
• JCP specification
http://www.jcp.org/en/jsr/detail?id=299
• GlassFish V3 Java EE 6 Reference Implementation
http://glassfish.dev.java.net
• The Aquarium
http://blogs.sun.com/theaquarium