Показаны сообщения с ярлыком паттерны. Показать все сообщения
Показаны сообщения с ярлыком паттерны. Показать все сообщения

суббота, 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;


пятница, 13 июля 2018 г.

Асинхронный вызов методов

При таком вызове метод выполняется в отдельном потоке не прерывая основной поток приложения. Иногда такой прием называют "паттерн асинхронность".
Spring
Класс конфигурации приложения надо отметить аннотацией @EnableAsync. Если это веб-приложение - то достаточно снабдить метод аннотацией @Async - и любой контейнер сервлетов (например Tomcat) запустит метод в отдельном потоке. Для десктоп-приложения надо будет добавить в класс конфигурации следующий бин:
@Configuration
@EnableAsync
public class AppContext {
   
    @Bean
    public TaskExecutor taskExecutor() {
        return new SimpleAsyncTaskExecutor();
    }
........................................
}

JavaEE
Такой же функционал обеспечивает контейнер EJB из "коробки" без всяких дополнительных настроек (начиная с JavaEE 6 - EJB 3.1 - Например TomEE v1.7.4 с профайлом jaxrs - http://tomee.apache.org/download-archive.html или http://openejb.apache.org/downloads.html ) - достаточно в бине EJB отметить метод аннотацией @Asynchronous - она применима для всех типов бинов EJB - @Stateless, @Stateful, @Singleton. Если отметить весь класс - то все его методы станут асинхронными.

среда, 4 июля 2018 г.

Потокобезопасный синглтон

Лучший способ создания одиночек в Java - использование Enum. Перечисления по своей сущности одиночки, так что JVM берет на себя большую часть работы по созданию одиночки. Таким образом, при использовании Enum  вы освобождаетесь от забот по синхронизации создания и обеспечения деятельности объекта и избегаете про­блем, связанных с инициализацией. Реализация паттерна Singleton на основе типа Enum:

publc enum MySingletonEnum {
      INSTANCE:
      public void doSomethinglnteresting () {.....}
}

Вы получаете ссылку на экземпляр одиночки следующим образом:

MySingletonEnum mse  =  MySingletonEnum.INSTANCE;

Как только у вас есть ссылка на одиночку, вы можете вызвать любой из его методов:

mse.doSomethinglnteresting();

четверг, 21 июня 2018 г.

Spring - класс JdbcDaoSupport и паттерн DAO

Паттерн DAO - Data Access Object - очень коротко - это когда все методы доступа к данным вы собираете (инкапсулируете) в одном классе.
Класс JdbcDaoSupport является оболочкой для JdbcTemplate и позволяет удобно делать свои DAO расширяя класс JdbcDaoSupport - при этом в нашем классе для работы необходимо только указать через конструктор реализацию DataSource при создании экземпляра нашего DAO. Напишем свой класс DaoJDBC который расширяет класс JdbcDaoSupport и сделаем внедрение через конструктор бина, реализующего DataSource:

@Repository
public class DaoJDBC extends JdbcDaoSupport {
   
    @Inject   // или @Autowired
    public DaoJDBC(DataSource dataSource) {
        this.setDataSource(dataSource);
    }

    public void clearAll() {
        String sql = "delete from hosts";
        this.getJdbcTemplate().update(sql);
    }
.................// + другие операции с базой
}
при этом экземпляр JdbcTemplate будет создан автоматически и будет доступен из нашего DAO через this.getJdbcTemplate() - дальше в классе DaoJDBC нам доступен весь инструментарий JdbcTemplate через this.getJdbcTemplate().

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

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