SlideShare une entreprise Scribd logo
1  sur  130
Промышленное программирование
Сборка проекта
Использование готового кода
Утилиты
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

Contenu connexe

Tendances

Клиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхКлиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталях
Kirill Zotin
 
Yii development
Yii developmentYii development
Yii development
MageCloud
 
Java весна 2013 лекция 8
Java весна 2013 лекция 8Java весна 2013 лекция 8
Java весна 2013 лекция 8
Technopark
 
Java осень 2013 лекция 8
Java осень 2013 лекция 8Java осень 2013 лекция 8
Java осень 2013 лекция 8
Technopark
 
ук 03.002.01 2011
ук 03.002.01 2011ук 03.002.01 2011
ук 03.002.01 2011
etyumentcev
 
Java осень 2012 лекция 8
Java осень 2012 лекция 8Java осень 2012 лекция 8
Java осень 2012 лекция 8
Technopark
 

Tendances (20)

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

En vedette

En vedette (13)

Programming Java - Lection 01 - Basics - Lavrentyev Fedor
Programming Java - Lection 01 - Basics - Lavrentyev FedorProgramming Java - Lection 01 - Basics - Lavrentyev Fedor
Programming Java - Lection 01 - Basics - Lavrentyev Fedor
 
Programming Java - Lection 06 - Multithreading - Lavrentyev Fedor
Programming Java - Lection 06 - Multithreading - Lavrentyev FedorProgramming Java - Lection 06 - Multithreading - Lavrentyev Fedor
Programming Java - Lection 06 - Multithreading - Lavrentyev Fedor
 
Industrial Programming Java - Lection Pack 02 - Distributed applications - La...
Industrial Programming Java - Lection Pack 02 - Distributed applications - La...Industrial Programming Java - Lection Pack 02 - Distributed applications - La...
Industrial Programming Java - Lection Pack 02 - Distributed applications - La...
 
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev FedorProgramming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
Programming Java - Lection 07 - Puzzlers - Lavrentyev Fedor
 
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev FedorProgramming Java - Lecture 02 - Objects - Lavrentyev Fedor
Programming Java - Lecture 02 - Objects - Lavrentyev Fedor
 
Programming Java - Lection 03 - Classes - Lavrentyev Fedor
Programming Java - Lection 03 - Classes - Lavrentyev FedorProgramming Java - Lection 03 - Classes - Lavrentyev Fedor
Programming Java - Lection 03 - Classes - Lavrentyev Fedor
 
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev FedorProgramming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
Programming Java - Lection 04 - Generics and Lambdas - Lavrentyev Fedor
 
Ciclos
CiclosCiclos
Ciclos
 
Top 15 Adventures Destinations You Should Try Out
 Top 15 Adventures Destinations You Should Try Out Top 15 Adventures Destinations You Should Try Out
Top 15 Adventures Destinations You Should Try Out
 
Fisioterapia
FisioterapiaFisioterapia
Fisioterapia
 
rocio roa
rocio roarocio roa
rocio roa
 
Arquitectura risc
Arquitectura riscArquitectura risc
Arquitectura risc
 
P7
P7P7
P7
 

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

Глава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansГлава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeans
metaform
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
drupalconf
 
Как не утонуть в мегабайтах JS-кода
Как не утонуть в мегабайтах JS-кодаКак не утонуть в мегабайтах JS-кода
Как не утонуть в мегабайтах JS-кода
tfmailru
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
PVasili
 
Zend Framework и мультиязычность
Zend Framework и мультиязычностьZend Framework и мультиязычность
Zend Framework и мультиязычность
Stepan Tanasiychuk
 

Similaire à Industrial Programming Java - Lection Pack 01 - Building an application - Lavrentyev Fedor (20)

Введение в maven
Введение в mavenВведение в maven
Введение в maven
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)
 
использование Hibernate java persistence.part 1.
использование Hibernate java persistence.part 1.использование Hibernate java persistence.part 1.
использование Hibernate java persistence.part 1.
 
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
 
JSSDK: Начало
JSSDK: НачалоJSSDK: Начало
JSSDK: Начало
 
Глава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansГлава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeans
 
Менеджер пакетов NuGet
Менеджер пакетов NuGetМенеджер пакетов NuGet
Менеджер пакетов NuGet
 
Оптимальная архитектура масштабируемого плагина WordPress на Custom Post Type...
Оптимальная архитектура масштабируемого плагина WordPress на Custom Post Type...Оптимальная архитектура масштабируемого плагина WordPress на Custom Post Type...
Оптимальная архитектура масштабируемого плагина WordPress на Custom Post Type...
 
Apache maven in java projects
Apache maven in java projectsApache maven in java projects
Apache maven in java projects
 
Java осень 2014 занятие 1
Java осень 2014 занятие 1Java осень 2014 занятие 1
Java осень 2014 занятие 1
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
системы сборок проектов
системы сборок проектовсистемы сборок проектов
системы сборок проектов
 
Sumin
SuminSumin
Sumin
 
Как не утонуть в мегабайтах JS-кода
Как не утонуть в мегабайтах JS-кодаКак не утонуть в мегабайтах JS-кода
Как не утонуть в мегабайтах JS-кода
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NET
 
Web deployment
Web deploymentWeb deployment
Web deployment
 
Сергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3CСергей Константинов — Что интересного готовит нам W3C
Сергей Константинов — Что интересного готовит нам W3C
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
Курс Java-2016. Занятие 08. Итераторы, многопоточность
Курс Java-2016. Занятие 08. Итераторы, многопоточностьКурс Java-2016. Занятие 08. Итераторы, многопоточность
Курс Java-2016. Занятие 08. Итераторы, многопоточность
 
Zend Framework и мультиязычность
Zend Framework и мультиязычностьZend Framework и мультиязычность
Zend Framework и мультиязычность
 

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