В этом посте мы сосредоточимся на 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
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
Context
>
<
Manager
pathname
=
""
/>
<!-- disables storage of sessions across restarts -->
<
Resource
name
=
"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 @RequestScoped public class UserService { @Inject UserDAO userDAO; //... } //Servlet - UserController public 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, поддерживается асинхронная обработка.
Вот и все на сегодня. Любые комментарии или предложения приветствуются.
- Вы можете найти исходный код здесь .