суббота, 14 июля 2018 г.

Способы создания/уничтожения бинов и паттерн "фабрика"

Коротко - паттерн "фабрика" - это реализация класса который обеспечивает настройку, создание и получение обьектов с помощью фабричных методов.
Spring
Вы можете отмечать классы аннотациями @Component, @Service, @Repository, @Controller, @Named - и тогда при наличии аннотации @ComponentScan для класса конфигурации приложения контейнер Spring автоматически определит бины и внедрит их куда нужно. Также бины можно создавать с помощью настроек XML - но мы это не будем рассматривать. Есть еще способ - это фабричные методы в классе конфигурации приложения, отмеченные аннотацией @Bean. Наиболее яркий пример - это бин, реализующий интерфейс DataSource. Вот класс конфига приложения:
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"PKG"})
public class AppContext {

    @Bean(destroyMethod = "close")
    public DataSource dataSource() {
        BasicDataSource bds = new BasicDataSource();
        bds.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
        bds.setUrl("jdbc:derby:./db/primer");
        bds.setPassword("12345");
        bds.setUsername("romka");
        return bds;
    }
....................   
}
Теперь можно внедрить этот бин куда и как угодно - через поле / метод / конструктор, например:
@Inject
private DataSource ds;
JavaEE CDI
Таким же функционалом обладает контейнер CDI JavaEE - только здесь такие фабричные методы называют продюсерами а используются аннотации @Produces и @Disposes и использовать их можно в любом бине CDI, аналог примера выше для CDI:
@Named
public class DSproducer {

    @Produces @ApplicationScoped
    @Named("ds") 
     public DataSource dataSource() {
        BasicDataSource bds = new BasicDataSource();
        bds.setDriverClassName("org.apache.derby.jdbc.EmbeddedDriver");
        bds.setUrl("jdbc:derby:./db/primer");
        bds.setPassword("12345");
        bds.setUsername("romka");
        return bds;
    }

    public void dsClose (@Disposes DataSource ds) {
        ds.close();
    }

}
отметим, что аннотация  @Disposes применяется к параметру метода уничтожения и кроме того - методы создания и уничтожения бина должны быть в одном классе. По сути @Produces - это аналог @Bean, а метод уничтожения с аннотацией @Disposes - это аналог параметра "destroyMethod" аннотации @Bean из Spring. Метод уничтожения вызывается по окончании действия контекста данного бина (здесь - @ApplicationScoped).
И да - точно так же теперь можно внедрить этот бин куда и как угодно - через поле / метод / конструктор (все эти способы контейнер CDI поддерживает точно так же как и Spring), например:
@Inject
private DataSource ds;


Комментариев нет:

Отправить комментарий

Взаимодействие между приложениями и Watch Service

Взаимодействие между разными приложениями Java можно сделать с помощью файловой системы, базы данных и JMS. Рассмотрим случай ФС - в Java ...