В этом посте мы сосредоточимся на CDI и Servlet 3.0. Вы можете увидеть часть 1 здесь .
Давайте начнем с CDI.
Когда я начал писать пост о происхождении этой серии, я не думал писать о CDI. Чтобы быть искренним, я никогда не использовал это раньше. Идея поста состояла в том, чтобы создать краду с использованием джедаев и сервлетов. Но когда я писал приложение, я просто ненавидел идею создавать бины. В своей повседневной работе я использую Spring для внедрения зависимостей и прочего, но для этого поста я не хотел бы добавлять его. Итак, я решил попробовать CDI, и я был очень удивлен, насколько просто добавить и использовать его в приложении.
Итак, что такое CDI?
CDI — это аббревиатура для внедрения контекста и зависимости, это спецификация javaee для адресации DI на платформе javaee. Поэтому, как только он активирован в вашем проекте, вы можете легко добавить зависимость, используя аннотацию @Inject . На CDI все является бобом,
и почти все классы могут быть введены.
Как активировать CDI?
Если мы запускаем наше приложение на сервере приложений Java EE, нам нужно только добавить пустой файл beans.xml в нашу папку META-INF. Но на таких серверах, как tomcat, нам нужно добавить еще несколько файлов и конфигураций:
- Добавьте weld-servlet.jar в папку lib. Вы можете получить его с сайта Weld;
- Создайте файл context.xml в разделе META-INF:
12345678
<?xmlversion="1.0"encoding="UTF-8"?><Context><Managerpathname=""/><!-- disables storage of sessions across restarts --><Resourcename="BeanManager"auth="Container"type="javax.enterprise.inject.spi.BeanManager"factory="org.jboss.weld.resources.ManagerObjectFactory"/></Context> - Добавьте некоторые конфигурации сварных швов в web.xml:
01020304050607080910
<listener><listener-class>org.jboss.weld.environment.servlet.Listener</listener-class></listener><resource-env-ref><resource-env-ref-name>BeanManager</resource-env-ref-name><resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type></resource-env-ref> - Тогда нам нужно только добавить пустой файл beans.xml в META-INF или WEB-INF.
После этого мы готовы начать кодирование с CDI.
В последнем посте мы создали класс UserDAO , в методах которого мы использовали экземпляр класса Jedis для выполнения команд Redis. Этот экземпляр был внедрен в объект UserDAO с помощью аннотации @Inject . Мы можем видеть это ниже:
|
1
2
3
4
5
|
public class UserDAO { @Inject Jedis jedis; //....} |
Как мы видим, внедрить экземпляр класса Jedis так просто. Если бы у класса Jedis был конструктор без аргумента, он был бы введен напрямую. Но это не так, поэтому мы использовали класс с методом, аннотированным @Produces . Это указывает на то, что это метод производителя. В нашем примере мы также использовали JedisPool, откуда мы получаем соединения Jedis. В этом случае у нас есть два производителя:
- Для джедаев
- Другое для джедаев .
У производителя Jedis есть экземпляр JedisPool, внедренный через @Inject , мы можем видеть их ниже:
JedisPoolFactory:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
public class JedisPoolFactory { private String host = "localhost"; private JedisPool jedisPool; @Singleton public @Produces JedisPool getJedisPool(){ jedisPool = new JedisPool(new JedisPoolConfig(), host); return jedisPool; } public void detroy(@Disposes JedisPool jedisPool){ jedisPool.destroy(); }} |
В коде мы видим, что метод getJedisPool аннотируется @Produces, говоря, что он является производителем экземпляров JedisPool. В этом коде мы видим также две другие аннотации.
- @Singleton — говоря, что возвращаемый экземпляр является одиночным, это означает, что будет только один экземпляр этого класса;
- @Disposes — указывает, какой метод следует вызывать при уничтожении экземпляра JedisPool;
Теперь мы можем увидеть JedisConnectionFactory :
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
public class JedisConnectionFactory { @Inject private JedisPool jedisPool; @Produces public Jedis getJedis(){ return jedisPool.getResource(); } public void returnResource(@Disposes Jedis jedis){ System.out.println("Returning jedis Connection"); jedisPool.returnResource(jedis); }} |
Чтобы получить экземпляр Jedis, классу нужен экземпляр JedisPool . JedisPool внедряется через @Inject и создается методом продюсера, который мы видели в последнем коде. Он также имеет @Disposes, который просто возвращает соединение с пулом .
Таким образом, мы можем внедрить экземпляр Jedis в DAO. Затем в других классах мы просто используем @Inject , как мы видим в классе Service и Servlet:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
//UserService@RequestScopedpublic class UserService { @Inject UserDAO userDAO;//...}//Servlet - UserControllerpublic class UserController extends HttpServlet { private static final long serialVersionUID = 1L; @Inject UserService userService;//...} |
В этом примере мы видим, как просто добавить и использовать CDI в приложении.
Сервлет 3.0
Основное отличие новых сервлетов в том, что нам не нужно объявлять их в web.xml , теперь мы можем просто установить параметры сервлета с помощью аннотаций. В сервлете, который мы создали в нашем примере, мы использовали аннотацию, чтобы установить отображение URL для нашего сервлета. Кто уже разработал сервлет раньше, знает, что это одна из конфигураций, которую мы должны добавить в web.xml. Мы можем видеть это в сервлете ниже:
|
01
02
03
04
05
06
07
08
09
10
11
|
@WebServlet("/UserController")public class UserController extends HttpServlet { private static final long serialVersionUID = 1L; @Inject UserService userService;//...//.. doGet//.. doPost} |
В приведенном выше коде мы говорим, что сервлет ответит на путь / UserController. С помощью этой аннотации мы можем добавить больше конфигураций, таких как:
|
1
|
@WebServlet(value="/UserController", name="userServlet") |
В приведенном выше коде мы объявили отображение и имя сервлета. Существуют и другие аннотации для упрощения использования сервлетов api, такие как @WebInitParam, @WebListener, @WebFilter . Мы не будем говорить о них, но вы можете найти о них большие ресурсы. Также, начиная с сервлетов 3.0, поддерживается асинхронная обработка.
Вот и все на сегодня. Любые комментарии или предложения приветствуются.
- Вы можете найти исходный код здесь .