SlideShare a Scribd company logo
Промышленное программирование
Сборка проекта
Использование готового кода
Утилиты
public String join(String sep, Object… tokens) {
StringBuilder sb = new StringBuilder();
for (Object token : tokens) {
if (!sb.isEmpty()) {
sb.append(sep);
}
sb.append(token);
}
return sb.toString();
}
Утилиты
import com.google.guava....Joiner;
Joiner.on(“,”).join(anything);
Сборка и деплой
cd myProject
javac $(find src/ -name “*.java”)
# Noo, what about classpath?
export CLASSPATH=lib/...
javac $(find src/ -name “*.java”)
# Noo, what about cleaning?
rm -rf target/
javac $(find src/ -name “*.java”)
# Noo, what about download some libraries?
wget http://repo1.maven.org/maven2/log4j/log4j/1.2.17/log4j-
1.2.17.jar
javac $(find src/ -name “*.java”)
# Oh, sorry, no compiler for Java 8 =(
# FFFFFFFFFFFUUUUUUUUUUUUU!!!!!1111
Сборка и деплой
mvn clean install
Инициализация
Service service = new ServiceImpl();
FooHandler handler = new FastFooHandler(HANDLE_SPEED);
service.setHandler(handler);
int importantParameter = Integer.parseInt(args[1])
service.setImportantParameter(importantParameter);
Listener l1 = new LazyListener();
Listener l2 = new DilligentListener();
service.setListeners(Arrays.asList(l1, l2));
service.init();
Инициализация
class ServiceImpl implements Service {
@Autowired
Handler handler;
@Autowired
List<Listener> listeners;
@Value(“#{args[1]}”)
int importantParameter;
@PostConstruct
void init() { … }
}
У Java очень большое сообщество
Все ваши задачи кто-то уже решил
К любому сервису кто-то уже написал API
К каждому багу кто-то уже настругал
костыль workaround
Общие библиотеки
Подробно документированы
Обильно обсуждены на форумах
Почти стабильно работают
Доступны для скачивания в репозиториях
Google Guava
Обертки над объектами и исключениями
Новые коллекции, Immutable-коллекции
Функциональщина
Многопоточность
Кеширование
Работа со строками
Хеш-функции
Работа с потоками и файловой системой
Волшебные Reflection
Apache Commons
Расширения для java.lang
Новые коллекции
Потоки и файловая система
Алгоритмы кодирования и хеширования
Сжатие и распаковка
Connection Pooling
…
Логгинг
java.util.logging (JUL)
Apache commons-logging
Log4j
SLF4j
Logback
Тестирование
JUnit
TestNG
Unitils
Mockito
JMock
Spring Test *
…
Как подключить библиотеку?
Apache Maven
Maven - “фреймворк для автоматизации
сборки проектов...” (с) Wikipedia
Конфигурируется декларативно на XML-
языке POM (Project Object Model)
Проект Maven ~= java-модуль
“Соглашение превыше конфигурации”
Maven репозиторий
Многие java-библиотеки публично
опубликованы как проекты Maven
Maven Project ~= java-библиотека + POM-
файл + ресурсы
Проекты доступны в центральном
репозитории Maven
http://search.maven.org/
Maven проекты
Каждый опубликованный maven-проект
имеет уникальный идентификатор
Идентификатор состоит из имени группы,
имени артефакта, версии.
Внутри проекта смежные артефакты
различаются т.н. классификатором
Пример проекта
com.google.guava:guava-gwt:17.0
Группа - com.google.guava
Артефакт - guava-gwt
Версия - 17.0
Неявный классификатор - jar
Структура проекта
/lection01
|-- src/
| |-- main/
| | |-- java/
| | | -- ru/fizteh/java/fediq/ # Структура пэкейджа
| | | -- LectionMain.java
| | -- resources/
| | -- config.properties
| -- test/
| -- java/
| -- ru/fizteh/java/fediq/
| -- LectionTest.java
-- pom.xml # конфигурация проекта
Пример конфигурации Maven
<project>
<modelVersion>4.0.0</modelVersion> # Волшебство
<groupId>ru.fizteh.java2.fediq</groupId> # Аналог package
<artifactId>lection-maven</artifactId> # Имя проекта
<version>1.0</version> # Версия
<dependencies>
<dependency> # Используемая библиотека
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>2.5.6</version>
</dependency>
</dependencies>
</project>
Конфигурация Maven
Жизненные циклы проекта Maven
Сборка состоит из этапов - жизненных циклов
(lifecycles)
Циклы выполняются последовательно, с
первого до целевого
Краткий список жизненных циклов - verify,
compile, test, install, deploy
Сборочная задача может быть присвоена
какому-то этапу или выполняться отдельно
Работа с Maven
$ mvn dependency:tree # Показать дерево зависимостей
$ mvn dependency:copy-dependencies # Скачать все зависимости
$ mvn compile # Скомпилировать код
$ mvn test # Запустить юнит-тесты
$ mvn package # Собрать (сжать и т.д.) артефакты
$ mvn install # Загрузить артефакт в локальный репозиторий
$ mvn deploy # Загрузить артефакт в удаленный репозиторий
$ mvn clean # Убрать за собой всякое
$ mvn clean install # Пересобрать проект
$ mvn install # = mvn validate compile test package install
...
Зависимости
Зависимости проекта перечисляются в
блоке <dependencies>
Maven умеет отслеживать транзитивные
зависимости
Во время сборки maven автоматически
скачает все необходимые файлы
Задача dependencies:copy-dependencies
сложит зависимости в директорию target/
Scopes
Scope - ситуация или этап, в котором
потребуется зависимость
provided - только для компиляции
runtime - только в рантайме
test - только в тесте
compile (default) - на стадии компиляции и в
рантайме
system - предоставляется окружением
Пример указания зависимостей
<dependencies>
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.8.0.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
Плагины
Задачи в maven поставляются плагинами
Плагин содержит в себе несколько целей
Плагины содержатся в тех же
репозиториях, что и другие проекты
Плагины также “достаются” автоматически
Плагин конфигурируется в pom-файле
Ряд плагинов подключен по умолчанию -
clean, compile, install, surefire и др.
Пример конфигурации плагина
<build>
...
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Пример конфигурации плагина
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
<skip>false</skip>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</plugin>
Пример конфигурации плагина
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration> <descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs> </configuration>
<executions>
<execution>
<id>someone-execution-id</id>
<phase>package</phase>
<goals> <goal>attached</goal> </goals>
</execution>
</executions>
</plugin>
JAR-файлы
По окончании сборки проект будет
упакован в jar-файл
jar - это обычный zip-архив, содежащий
скомпилированные классы и метаданные
При желании, в аналогичные jar-файлы
можно сохранить исходники, ресурсы и пр
На последней стадии (деплое) jar-файлы
заливаются в репозиторий
Наследование проектов
Для поддержки принципа DRY maven
поддерживает наследование проектов
Основная конфигурация производится в
“родительском” проекте
Дочерние проекты подключают его с
помощью тега <parent>
Часто родительский проект является
корнем “многомодульного” проекта
Многомодульные проекты
Группа близких проектов может быть
объединена в многмодульный проект
Все модули перечисляются в корневом
проекте в теге <modules/>
Также в корневом проекте указывается
<packaging>pom</packaging>
Пример - корневой проект
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>ru.fizteh.java2</groupId>
<artifactId>parent-pom</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
<modules>
<module>example-jdbc</module>
<module>example-spring</module>
</modules>
<build/> ...
<dependencies/> ...
</project>
Пример - дочерний проект
<project>
<parent>
<groupId>ru.fizteh.java2</groupId>
<artifactId>parent-pom</artifactId>
<version>1.0</version>
</parent>
<groupId/> <version/> … # Унаследованные параметры можно перезаписывать
<artifactId>example-jdbc</artifactId>
<packaging>jar</packaging>
<dependencies/> ...
</project>
Рекомендуемая литература
Компоновка приложения
Промышленное программирование
Связанность кода
http://infomgmt.wordpress.com/
Больше кода - сложнее работать
Со временем число сущностей растет
Число связей растет на порядок быстрее
Если не предпринять мер, быстро
наступает коллапс разработки
И это очень частая проблема
Финансовые аспекты
Сложность рефакторинга
Сложность изменения API
Время вхождения (нового разработчика)
Коэффициент автобуса
Логическая компонента
Компонента - автономная логическая
единица кода
Внутри компоненты происходит
контролируемое тесное взаимодействие
Наружу предоставляется API (контракт)
Компонента взаимодействует с соседями
через их API
Слабая связанность
http://infomgmt.wordpress.com/
Сильная связанность
http://infomgmt.wordpress.com/
Закон Деметры
Если у A есть доступ к Б
и у Б есть доступ к В,
то А не нужен доступ к В
Уровни связанности
Содержимое
Общее состояние
Внешний контракт
Структура данных
Сообщения
Нет связности
Связность (сцепление) компоненты
Компонента должна быть осмысленна
Ее части должны иметь что-то общее
Связность - мера взаимосвязи между
составными частями одной компоненты
Принцип наименьшего удивления
опирается на связность
Типы связности (сцепления)
Функциональная
Последовательная
Временная/процедурная
Логическая/тематическая
Случайная
Фрактальная природа компоненты
Компонента создана на основе маленьких
составных частей
Их разработчик рассматривал каждую
такую часть как отдельную компоненту
Ваша сложная система - на самом деле,
одна из компонент в бизнес-процессе
Фрактальная природа компоненты
Основная идея проектирования
Меньше связанность - больше сцепление
Модульность
Модульность - принцип разработки ПО,
согласно которому код разделяется на
отдельные функционально законченные
сущности - модули
Это позволяет переиспользовать код
Это упрощает проектирование
Это упрощает дистрибуцию (см. Maven)
SPI - набор интерфейсов, предлагаемый к
реализации пользователями
API - набор моделей, интерфейсов и т.п.,
реализованный модулем
Контракт - формальное соглашение об
использовании модуля
Contract-first Development - парадигма
разработки “от контракта”
SPI, API, контракт
Интерфейс и реализация
Как правило, API модуля не содержит
сложных конструкций и зависимостей
Внешние интерфейсы (API) модуля можно
выделить в отдельный легкий модуль
Реализация остается в отдельном тяжелом
модуле, о котором пользователи могут не
знать
Зависимости между модулями
Переизбыток зависимостей в системе
вызывает непредсказуемые проблемы
Разделение реализации и интерфейса
сильно сокращает объем знаний и
зависимостей, необходимый для
использования модуля
Внедрение зависимостей
Пример прямого управления
void main() {
Brain brain = new MonkeyBrain();
Tail tail = new FishTail();
TeethHolder teeth = new SharkJaws();
//Animal animal = new FourLimbedMonster();
FourLimbedMonster animal = new FourLimbedMonster();
animal.setTail(tail);
animal.setTeethHolder(teeth);
animal.doHunt(); // NoSuchBrainException
}
Пример прямого управления
void main() {
Brain brain = new MonkeyBrain();
Tail tail = new FishTail();
TeethHolder teeth = new SharkJaws();
Animal animal = new FourLimbedMonster(brain, tail, teeth);
animal.doHunt();
}
Встроим зависимости
interface DependencyInjector {
void put(Object o);
<T> T get(Class<T> clazz);
}
Встроим зависимости
class FourLimbedMonster implements Animal {
Brain brain;
TeethHolder teeth;
Tail tail;
public FourLimbedMonster(DependencyInjector di) {
brain = di.get(Brain.class);
teeth = di.get(TeethHolder.class);
tail = di.get(Tail.class);
}
}
Встроим зависимости
void main() {
DependencyInjector di = new DependencyInjectorImpl();
di.put(new MonkeyBrain());
di.put(new FishTail());
di.put(new SharkJaws());
Animal animal = new FourLimbedMonster(di);
animal.doHunt();
}
Выделим зависимости в модули
class ModuleWithBodyParts {
public static void fillBodyParts(DependencyInjector di) {
di.put(new MonkeyBrain());
di.put(new FishTail());
di.put(new SharkJaws());
}
}
class ModuleWithAnimal {
public static Animal buildAnimal(DependencyInjector di) {
return new FourLimbedMonster(di);
}}
Выделим зависимости в модули
void main() {
DependencyInjector di = new DependencyInjectorImpl();
ModuleWithBodyParts.fillBodyParts(di);
Animal animal = ModuleWithAnimal.buildAnimal(di);
animal.doHunt();
}
Обобщим еще немного
interface DependenciesSource {
void fill(DependencyInjector di);
}
void main(List<DependenciesSource> sources) {
DependencyInjector di = new DependencyInjectorImpl();
for (DependenciesSource source : sources) {
source.fill(di);
}
di.get(Animal.class).doHunt();
}
Spring Framework
Промышленное программирование
Хочется Dependency Injection?
Spring Framework
Мощная инфраструктурная платформа для
создания сложного JVM-based ПО
Интеграция со множеством популярных
фреймворков, внешних сервисов и JSR
Сквозная концепция программирования
Огромное сообщество
Де-факто стандарт Java-платформы
Из коробки:
Application Context - DI и каталог ресурсов
Интеграция с БД (JDBC, ORM, транзакции)
Web - Servlets, MVC, JSP, REST, ...
XML и JSON биндинги
SpEL - язык для управления ресурсами
AOP, Instrumentation и прочий сатанизм
Тестирование с JUnit и TestNG
...
Пример из жизни
public interface Brain {
String getIdea();
}
public interface Animal {
String doHunt();
}
Пример из жизни
public class MonkeyBrain implements Brain {
public String getIdea() {
return "Banana";
}
}
Пример из жизни
public class Kitten implements Animal {
private Brain brain;
public void setBrain(Brain brain) {
this.brain = brain;
}
public String doHunt() {
return String.format("Meow, %s!",
brain.getIdea());
}
}
Пример из жизни
import org.springframework.context.ApplicationContext;
void main() {
ApplicationContext ctx = ...; // Magic
Animal animal = ctx.getBean(Animal.class);
animal.doHunt(); // Meow, Banana!
}
XML-based заклинания
Spring XML config
<beans ... >
<bean name="someoneBrain" class="MonkeyBrain"/>
<bean name="kitten" class="Kitten">
<property name="brain" ref="someoneBrain"/>
</bean>
</beans>
Шапка выглядит так
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
Autowiring
<beans ... >
<bean name="someoneBrain" class="MonkeyBrain"/>
<bean name="kitten" class="Kitten" autowire=”byType”/>
<bean name="kitten" class="Kitten">
<property name="brain" ref="someoneBrain"/>
</bean>
</beans>
Autowiring by default
<beans ... default-autowire="byType">
<bean name="someoneBrain" class="MonkeyBrain"/>
<bean name="kitten" class="Kitten"/>
</beans>
Запуск контекста
void main() {
ApplicationContext ctx =
new ClassPathXmlApplicationContext("ctx.xml");
Animal animal = ctx.getBean(Animal.class);
animal.doHunt(); // Meow, Banana!
}
Annotation-based заклинания
@Component annotation
@Component
public class MonkeyBrain implements Brain {
public String getIdea() {
return "Banana";
}
}
@Autowired annotation
@Component
public class Kitten implements Animal {
@Autowired
private Brain brain;
public String doHunt() {
return String.format("Meow, %s!",
brain.getIdea());
}
}
Запуск контекста
void main() {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext();
ctx.scan(“package.name”);
ctx.refresh();
Animal animal = ctx.getBean(Animal.class);
System.out.println(animal.doHunt());
}
Animal animal = ctx.getBean(Animal.class);
animal.doHunt(); // Meow, Banana!
}
@Configuration и
@ComponentScan
@Configuration
@ComponentScan("package.name")
public class AnimalsConfig {
@Bean
public Brain fishBrain() {
return new Brain() {
public String getIdea() {return "Bobble";}
};
}
}
Запуск контекста
void main() {
ApplicationContext ctx = new
AnnotationConfigApplicationContext(AnimalsConfig.class);
Animal animal = ctx.getBean(Animal.class);
animal.doHunt(); // Meow, Bobble!
}
Жизненный цикл контекста
Bean Lifecycle
1.Расчитывается граф (DAG) зависимостей
2.Инициализируются зависимости бина
3.Выставляются ссылки на зависимости
4.Запускаются инициализаторы
5.Бин живет, контекст запущен
6.Запускаются деструкторы
7.Граф зависимостей уничтожается в
обратном порядке
InitializingBean и DisposableBean
interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
interface DisposableBean {
void destroy() throws Exception;
}
Пример DisposableBean
class ClosableOne impelements Closable, DisposableBean {
@Overwrite
public void close() throws IOException { … }
@Overwrite
public void destroy() throws Exception {
close();
}
}
@PostConstruct и @PreDestroy
class NamedOne implements Closable {
@Autowired private String name;
private String formattedName;
@PostConstruct
public void init() {formattedName = format(name);}
@PreDestroy
@Overwrite
public void close() { … }
}
Awares
interface BeanNameAware {
void setBeanName(String name) …;
}
interface ResourceLoaderAware {
void setResourceLoader(ResourceLoader loader) …;
}
interface ApplicationContextAware {
void setApplicationContext(ApplicationContext ctx) …;
}
@Lazy
@Lazy
@Service
class ReallyHardService {
@PostConstruct
void veryLongInitializing() { … };
void almostUselessMethod() { … };
}
Рекомендуемая литература
Maven dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.6.RELEASE</version>
<scope>test</scope>
</dependency>
Окружение и запуск
Промышленное программирование
Ресурсы приложения
Как передать коэффициент в бин?
class CalibratingOne {
@Autowired // Any double?!
double coefficient;
@Autowired // Other any double?!
double scale;
}
@Value
class CalibratingOne {
@Value(“${property.name}”)
double coefficient;
@Value(“${prop.scale:1.0}”)
double scale; // здесь 1.0 - дефолтное значение
}
PropertiesPlaceholderConfigurer
@Configuration
@PropertySource(“classpath:application.properties”)
class ApplicationConfiguration {
@Bean
public PropertiesPlaceholderConfigurer props() {
return new PropertiesPlaceholderConfigurer();
}
}
.properties-файлы
ru.fizteh.java2.example3.coefficient=5.0
ru.fizteh.java2.example3.scale=0.8
# comments allowed
ru.fizteh.java2.mysql.port=3306
ru.fizteh.java2.mysql.user=fediq
ru.fizteh.java2.mysql.password=Very$tr0ngPa66w*rd
System properties
java … 
-Dru.fizteh.app.mode=yarr 
-Dru.fizteh.app.count=133 
… 
ru.fizteh.app.MainClass 
command line args
@Resource
@Service
class CheapCalculator implements BillCalculator {
Bill calcCost(Order order) {
return new Bill(order.getCosts());
}
}
@Service
class CostyCalculator implements BillCalculator {
Bill calcCost(Order order) {
return new Bill(order.getCosts() * 2);
}
}
@Resource
class OrderProcessor {
@Autowired // which one?
BillCalculator billCalculator;
public BigDecimal processOrder(Order order) {
return billCalculator.calcCost(order).getPrice();
}
}
@Resource
class OrderProcessor {
@Resource(name = “cheapCalculator”)
BillCalculator billCalculator;
public BigDecimal processOrder(Order order) {
return billCalculator.calcCost(order).getPrice();
}
}
@Resource
@Service // = @Service(“cheapCalculator”) // Default name
class CheapCalculator implements BillCalculator {
Bill calcCost(Order order) {
return new Bill(order.getCosts());
}
}
@Service(“ohohoCalculator”) // Custom name
class CostyCalculator implements BillCalculator {
Bill calcCost(Order order) {
return new Bill(order.getCosts() * 2);
}
}
class OrderProcessor {
Взятие бинов из контекста
class Cook {
@Autowired // like ApplicationContextAware
ApplicationContext ctx;
public void cook() {
Pan pan = ctx.getBean(Pan.class)
Map<String, Food> namedFood =
ctx.getBeansOfType(Food.class);
Food fish = ctx.getBean(“fish”, Food.class);
}
}
Взятие параметров из контекста
class Accountant{
@Autowired // like ApplicationContextAware
ApplicationContext ctx;
public void report() {
Environment env = ctx.getEnvironment();
String cardHolder = env.getProperty(“cardHolder”);
double tax = env.getPropertyAsClass(“tax”,
Double.class)
}
}
Взятие файлов из контекста
class Reader {
@Autowired // like ResourceLoaderAware
ResourceLoader loader; // вообще-то, это тот же
контекст
public void read() {
Resource resource =
loader.getResource(“file.txt”);
URI uri = resource.getURI();
String body = IOUtils.toString( // apache commons-
io
resource.getInputStream());
}
}
Non-required wiring
class Logger {
@Autowired(required = false)
Printer printer;
public void log(String s) {
if (printer != null) {
printer.print(s);
}
…
}
}
SLF4J + Log4J
Использование логгера
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class SomeoneActor {
private static final Logger log =
LoggerFactory.getLogger(SomeoneActor.class);
void doSomething(Object event) {
log.warn(“Oh, god, {} happens!”, event);
}
}
Использование логгера
void doSomethingWrong(String arg) {
try {
doSomethingBad(arg);
} catch (AnyException e) {
log.error(“Bad with {} happens”, arg, e)
// Если последний аргумент - исключение,
// то в лог будет выведен stack trace
}
}
Уровни логгинга
trace - “шаг левой… шаг правой…”
debug - “идем прямо… все еще идем...”
info - “надо идти прямо 32 км”
warn - “пришлось обойти лужу”
error - “потерял карту, упал в яму, промок”
fatal - (в SLF4J нет) “сломал обе ноги,
прощай, жестокий мир”
Maven Dependencies
<!-- SLF4J core API --!>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<!-- SLF4J to Log4J bridge --!>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<!-- Log4J implementation --!>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j.xml
<log4j:configuration>
<appender .../>
<category .../>
<root .../>
</log4j:configuration>
log4j.xml header
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration
xmlns:log4j="http://jakarta.apache.org/log4j/">
log4j.xml category
<category name="ru.fizteh">
<priority value="ALL"/> <!-- Most important --!>
</category>
<category name="wire">
<priority value="NONE"/> <!-- NO U!!! --!>
</category>
<category name="org.springframework">
<priority value="WARN"/> <!-- Don’t worry --!>
</category>
log4j.xml appender
<appender name="console"
class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value=
"%-d{ISO8601} [%15.15t] %-5p %30.30c - %m%n"/>
</layout>
</appender>
Conversion Pattern explained
%d{ISO8601} - дата в формате ISO-8601
%p - приоритет (уровень логгинга)
%t - thread, имя потока
%c - имя логгера (имя класса)
%с{1} - последнее слово в имени логгера
%m - логируемое сообщение
%n - перевод строки
Conversion Pattern explained
printf-like formatting
До точки - минимальное число знаков
После точки - максимальное число знаков
С минусом - слева направо
Без минуса - справа налево
%-10.20c = поле от 10 до 20 символов,
заполнять слева направо, имя класса
log4j.xml root
<root>
<!-- Прочие категории интересуют нас от INFO и выше --
>
<priority value="INFO"/>
<!-- Льем все в console -->
<appender-ref ref="console"/>
</root>
%-d{ISO8601} [%t] %-5p %20.20c %m%n
2014-09-14 00:47:42,912 [main] INFO .java2.ServerStarter Starting web server
2014-09-14 00:47:42,913 [main] DEBUG eh.java2.util.Reader Reading config.xml
2014-09-14 00:47:42,913 [main] DEBUG eh.java2.util.Reader Reading pages.xml
2014-09-14 00:47:42,913 [main] WARN eh.java2.util.Reader Cannot read trololo.xml
2014-09-14 00:47:42,914 [main] ERROR .java2.ServerStarter Failed to open socket
java.net.BindException: Permission denied
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:382)
at java.net.ServerSocket.bind(ServerSocket.java:375)
at java.net.ServerSocket.<init>(ServerSocket.java:237)
at java.net.ServerSocket.<init>(ServerSocket.java:128)
at ru.fizteh.java2.ServerStarter.openSocket(ServerStarter.java:30)
at ru.fizteh.java2.ServerStarter.main(ServerStarter.java:23)
Боевой запуск приложения
Что нужно сделать для запуска?
Допустим, компиляция уже завершена
Собрать библиотеки зависимостей,
собственные классы и файлы ресурсов
Построить из них classpath
Запустить JVM* с нужными аргументами
Иногда вместо отдельной JVM можно
запустить приложение в общем контейнере
Запуск через Shell-скрипт
#!/bin/sh
mvn clean package
mvn dependency:copy-dependencies
CLASSPATH=$(find target/ -name "*.jar" -printf "%f:")
java -cp $CLASSPATH 
-Dhard.coded.args=fixed.values 
-ru.fizteh.java2.MainClass "$@"
Упаковка в Web App Archive (.war)
# Нужны правки в pom.xml, смотрите их в следующих сериях
mvn clean compile war:war
# Копируем war-файл в Application Server
copy target/myapp.war $TOMCAT_HOME/webapps/
# При должной настройке приложение запустится само
# Подробнее о веб-приложениях в следующих сериях
chrome http://localhost:8080/myapp
Spring Boot
Набор библиотек, бесстыдно облегчающий
запуск Spring-based приложений
Автоматически конфигурирует Spring,
manifest.mf, Application Server, etc…
Тесно интегрирован с Maven и Gradle
Spring Boot Maven Plugin
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>1.1.6.RELEASE</version>
<executions>
<execution>
<goals><goal>repackage</goal></goals>
</execution>
</executions>
</plugin>
Spring Boot в коде
@Configuration
@EnableAutoConfiguration // Опционально
class AppConfig {
...
public static void main(String[] args) {
SpringApplication.run(AppConfig.class);
}
}
Запуск с помощью Spring Boot
mvn clean package # если в конфиге указан goal repackage
mvn clean package spring-boot:repackage # если не указан
# запуск прямо из maven
mvn spring-boot:run
# В repackaged jar упакованы зависимости и настроен main class
# Его можно распространять отдельно и запускать напрямую
java -jar target/app.jar

More Related Content

PPTX
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
PDF
Java осень 2014 занятие 8
PPTX
Programming Java - Lection 05 - Software Design - Lavrentyev Fedor
PPT
Cookies, session и другое в JSP
PPT
Эффективное программирование на NodeJS
PDF
Java осень 2014 занятие 7
PPTX
Расширение библиотеки Slick
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Java осень 2014 занятие 8
Programming Java - Lection 05 - Software Design - Lavrentyev Fedor
Cookies, session и другое в JSP
Эффективное программирование на NodeJS
Java осень 2014 занятие 7
Расширение библиотеки Slick

What's hot (20)

PDF
Клиент-серверное взаимодействие под android в деталях
PPT
Введение в Spring
PPT
Yii development
PPTX
Java весна 2013 лекция 8
PDF
Лекция Android. БД SQLite, ContentProvider, Loader
PDF
C# Web. Занятие 12.
PDF
Примеры решения типичных задач за рамками ядра Yii2
PDF
Android - 13 - Database
PDF
Java осень 2013 лекция 8
PDF
C# Web. Занятие 04.
PDF
YiiConf: Миграции и инсталляции
PDF
Лекция #7. Django ORM
PPT
Общая архитектура Yii2
ODP
PGDBObject
PPTX
Основы Java. 5. Databases
PPT
Jdbc in java
PDF
ук 03.002.01 2011
PDF
Продвинутое использование ActiveRecord в Yii2
PPTX
Java осень 2012 лекция 8
Клиент-серверное взаимодействие под android в деталях
Введение в Spring
Yii development
Java весна 2013 лекция 8
Лекция Android. БД SQLite, ContentProvider, Loader
C# Web. Занятие 12.
Примеры решения типичных задач за рамками ядра Yii2
Android - 13 - Database
Java осень 2013 лекция 8
C# Web. Занятие 04.
YiiConf: Миграции и инсталляции
Лекция #7. Django ORM
Общая архитектура Yii2
PGDBObject
Основы Java. 5. Databases
Jdbc in java
ук 03.002.01 2011
Продвинутое использование ActiveRecord в Yii2
Java осень 2012 лекция 8
Ad

Viewers also liked (13)

PPTX
Programming Java - Lection 01 - Basics - Lavrentyev Fedor
PPTX
Programming Java - Lection 06 - Multithreading - Lavrentyev Fedor
PPTX
Industrial Programming Java - Lection Pack 02 - Distributed applications - La...
PPTX
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
PPTX
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
PPTX
Programming Java - Lection 03 - Classes - Lavrentyev Fedor
PPTX
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
PPTX
PPTX
Top 15 Adventures Destinations You Should Try Out
PPTX
Fisioterapia
PPTX
Arquitectura risc
PDF
Programming Java - Lection 01 - Basics - Lavrentyev Fedor
Programming Java - Lection 06 - Multithreading - Lavrentyev Fedor
Industrial Programming Java - Lection Pack 02 - Distributed applications - La...
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lection 03 - Classes - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Top 15 Adventures Destinations You Should Try Out
Fisioterapia
Arquitectura risc
Ad

Similar to Industrial Programming Java - Lection Pack 01 - Building an application - Lavrentyev Fedor (20)

PPTX
Cистемы автоматической сборки проектов (Полина Фоминых)
PPTX
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 4
PDF
Введение в maven
PPTX
системы сборок проектов
PDF
Иван Крутов - Автоматизация сборки Java-проекта
ODP
Документирование исходных текстов (javadoc)
PPTX
Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты
PDF
Анатолий Кондратьев, Exigen Services
PDF
Apache Maven presentation from BitByte conference
PPTX
Maven 3 : уличная магия
PPT
Apache maven in java projects
PPT
Serge P Nekoval Grails
PDF
Groovy presentation.
PPT
Serge P Nekoval Grails
PPT
Grails. Поиски закончены.
PDF
Java осень 2014 занятие 1
PPT
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
PDF
Расширь границы возможного вместе с Gradle
PDF
Gradle Introduction
PDF
Android - 06 - Gradle
Cистемы автоматической сборки проектов (Полина Фоминых)
Спецкурс "Современные практики разработки ПО", 2013-2014 уч. год, занятие 4
Введение в maven
системы сборок проектов
Иван Крутов - Автоматизация сборки Java-проекта
Документирование исходных текстов (javadoc)
Стажировка-2013, разработчики, занятие 6. Внешние конфиги, сборка, автотесты
Анатолий Кондратьев, Exigen Services
Apache Maven presentation from BitByte conference
Maven 3 : уличная магия
Apache maven in java projects
Serge P Nekoval Grails
Groovy presentation.
Serge P Nekoval Grails
Grails. Поиски закончены.
Java осень 2014 занятие 1
Методики «Inversion of Control» и «Dependency Injection». Применение в Spring.
Расширь границы возможного вместе с Gradle
Gradle Introduction
Android - 06 - Gradle

Industrial Programming Java - Lection Pack 01 - Building an application - Lavrentyev Fedor