Portlet 3.0 (see JSR 362) supports Contexts and Dependency Injection (CDI) so you can create and use injectable classes (CDI beans) in your portlet. It also provides injectable portlet artifacts called Portlet Predefined Beans. They give a portlet’s CDI beans access to the portlet configuration, preferences, requests, responses, and more. Here’s how to create and use CDI beans and Portlet Predefined Beans:
-
Create a portlet WAR project, if you haven’t created one already.
- Any project that has a class that implements the
javax.portlet.Portlet
interface, either directly or indirectly.
- Any project that has a class that implements the
-
If your portlet WAR project isn’t a Bean Portlet, add this
src/main/webapp/WEB-INF/beans.xml
file to it. This file tells CDI to scan the project for CDI annotations.<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" bean-discovery-mode="all" version="1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"> <!-- This file is necessary in order to inform CDI that scanning should occur for CDI annotations. --> </beans>
-
Add the
@ApplicationScoped
annotation to your portlet class.import javax.enterprise.context.ApplicationScoped; @ApplicationScoped public class MyPortlet ... { ... }
-
Make sure all concrete classes you want to make injectable have the default constructor. These classes are now CDI beans.
-
Add a scope to each CDI bean.
Bean Scope Description @ApplicationScoped
Shares the bean’s state across all users’ interactions with the portlet. @Dependent
(default scope) Designates the bean to be for the client bean and share the client bean’s lifecycle. @PortletRequestScoped
Associates the bean with the portlet request. @PortletSessionScoped
Places the bean in the portlet session. @RenderStateScoped
Stores the bean as part of the portlet’s render state. Important: The bean must implement the PortletSerializable
interface. -
Use the JSR 330
@Inject
annotation in a CDI bean to inject another CDI bean into it. For example, this code informs Liferay DXP’s CDI bean container to inject aGuestBook
CDI bean into thisguestbook
field.@Inject private GuestBook guestbook;
-
Inject any Portlet Predefined Beans (portlet request scoped or dependent scoped beans) into your
@PortletRequestScoped
CDI beans.@PortletRequestScoped public class RequestProcessor ... { @Inject private PortletRequest portletRequest; ... }
-
Inject any dependent scoped Portlet Predefined Beans into your
ApplicationScoped
or@Dependent
scoped CDI beans. For example,@ApplicationScoped public class MyPortlet ... { @Inject private PortletConfig portletConfig; ... }
-
Use bean EL names to reference any portlet redefined named beans in your JSP or JSF pages.
-
Deploy your project.
Congratulations! You have created and used CDI beans and Portlet Predefined Beans in your portlet.