Java for Beginner
673 subscribers
541 photos
155 videos
12 files
827 links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Деплой приложений. Метод для контейнеризации приложений в Docker. Встреча от 08.12.2024

Запись нашей сегодняшней встречи -
YOUTUBE
RUTUBE

Спасибо всем кто пришел, за участие!💪

На сегодняшней встрече с подписчиками, мы на примере, разобрали:
— что такое архивы JAR, WAR и EAR и для чего они нужны.
— как создать и запускать приложения без IDea.
— как организовать сборку через основные сборщики Maven и Gradle.
— как создать простейшее веб-приложение и задеплоить его на сервер в Docker контейнер.

Смотрите, комментируйте, задавайте вопросы! Обязательно подписывайтесь на ютуб и рутюб каналы!!!

Всем хорошего настроения! 🫡✌️
Транзакционный менеджмент с помощью AOP

Транзакционный менеджмент — это одна из ключевых функций, где AOP в Spring используется наиболее активно. С помощью AOP можно автоматически управлять транзакциями, устраняя необходимость вручную начинать, коммитить или откатывать транзакции в бизнес-логике.


1. Транзакционный менеджмент: Основы

Транзакция — это единица работы, которая либо выполняется полностью, либо откатывается при возникновении ошибки. Примером транзакции может быть:
Добавление пользователя в базу данных.
Перевод денег между счетами.


Роль AOP в транзакционном менеджменте


Spring AOP позволяет автоматически обрабатывать транзакции:
Начинать транзакцию перед выполнением метода.
Фиксировать транзакцию после успешного выполнения.
Откатывать транзакцию при возникновении исключения.


Аннотация @Transactional

В Spring для работы с транзакциями используется аннотация @Transactional.

2. Пример использования транзакционного менеджмента

Шаг 1: Добавление зависимостей
Добавьте в pom.xml зависимости для Spring Data JPA и базы данных:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>


Шаг 2: Настройка базы данных
Добавьте настройки H2 в application.properties:
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect


Шаг 3: Бизнес-логика с транзакциями


Создайте сущность:
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;

@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private String name;
private double balance;

// Getters and Setters
}


Репозиторий для работы с данными:
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {}


Сервис с транзакционным методом:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserService {
private final UserRepository userRepository;

public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}

@Transactional
public void transferMoney(Long fromUserId, Long toUserId, double amount) {
User fromUser = userRepository.findById(fromUserId)
.orElseThrow(() -> new RuntimeException("User not found"));
User toUser = userRepository.findById(toUserId)
.orElseThrow(() -> new RuntimeException("User not found"));

fromUser.setBalance(fromUser.getBalance() - amount);
toUser.setBalance(toUser.getBalance() + amount);

userRepository.save(fromUser);
userRepository.save(toUser);

if (amount > 1000) {
throw new RuntimeException("Transfer limit exceeded!");
}
}
}


Шаг 4: Проверка

Создайте тестовый контроллер:
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/users")
public class UserController {
private final UserService userService;

public UserController(UserService userService) {
this.userService = userService;
}

@PostMapping("/transfer")
public void transferMoney(@RequestParam Long fromUserId, @RequestParam Long toUserId, @RequestParam double amount) {
userService.transferMoney(fromUserId, toUserId, amount);
}
}
Теперь, если перевести более 1000 единиц, метод выбросит исключение, а все изменения в базе данных будут откатаны.


#Java #Training #Spring #AOP #AOP_Transaction
Что выведет код?

public class Task091224_1 {
public static void main(String[] args) {
Random random = new Random(10);
System.out.println(random.nextInt(100));

random.setSeed(10);
System.out.println(random.nextInt(100));

Random anotherRandom = new Random(10);
System.out.println(anotherRandom.nextInt(100));

random.setSeed(20);
System.out.println(random.nextInt(100));
}
}


#Tasks
Варианты ответа:
Anonymous Quiz
38%
13 13 13 53
25%
23 54 23 87
25%
54 54 55 87
13%
23 23 54 64
Постарайся вообще прийти...🤪😂

https://t.me/Java_for_beginner_dev

#Mems
Все аннотации AOP и их использование

1. @Aspect

Обозначает класс как аспект.
@Aspect
@Component
public class LoggingAspect {
// Pointcut и Advice
}


2. @Pointcut

Определяет срез, на который будет ссылаться Advice.
@Pointcut("execution(* com.example.service.*.*(..))")
public void serviceLayer() {}


3. @Before

Совет, выполняющийся перед методом.
@Before("serviceLayer()")
public void logBefore() {
System.out.println("Before method");
}


4. @After

Совет, выполняющийся после метода, независимо от его результата.

@After("serviceLayer()")
public void logAfter() {
System.out.println("After method");
}


5. @AfterReturning

Совет, выполняющийся после успешного выполнения метода.
@AfterReturning(pointcut = "serviceLayer()", returning = "result")
public void logAfterReturning(Object result) {
System.out.println("Method returned: " + result);
}


6. @AfterThrowing

Совет, выполняющийся при выбросе исключения.
@AfterThrowing(pointcut = "serviceLayer()", throwing = "ex")
public void logAfterThrowing(Exception ex) {
System.out.println("Exception thrown: " + ex.getMessage());
}


7. @Around

Оборачивает метод, позволяя контролировать его выполнение.

@Around("serviceLayer()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before method");
Object result = joinPoint.proceed();
System.out.println("After method");
return result;
}


8.
@EnableAspectJAutoProxy

Включает поддержку AOP в приложении.
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {}


#Java #Training #Spring #AOP #AOP_Annotations
Введение в Spring Security

Spring Security — это мощный и гибкий фреймворк для обеспечения безопасности приложений на платформе Spring. Он предоставляет инструменты для аутентификации и авторизации, защищает от атак и позволяет интегрировать собственные механизмы безопасности.

1. Что такое Spring Security?


Spring Security решает две основные задачи:
Аутентификация — процесс проверки подлинности пользователя.
Авторизация — проверка прав пользователя для выполнения определённых действий.


Ключевые возможности:
Аутентификация и авторизация.
Интеграция с популярными механизмами безопасности (LDAP, OAuth2, JWT).


Защита от атак:
CSRF (Cross-Site Request Forgery).
XSS (Cross-Site Scripting).
Clickjacking.
Шифрование паролей.
Конфигурируемая модель безопасности с возможностью расширения.


2. Основные компоненты Spring Security

2.1 SecurityFilterChain
Основной компонент, который перехватывает HTTP-запросы и применяет к ним правила безопасности.

2.2 AuthenticationManager
Управляет процессом аутентификации. Это центральная точка, которая определяет, прошёл ли пользователь проверку подлинности.

2.3 UserDetailsService
Интерфейс, отвечающий за получение данных пользователя (например, имени и пароля) из базы данных.

2.4 PasswordEncoder
Интерфейс для шифрования и проверки паролей. Самый популярный его реализация — BCryptPasswordEncoder.

2.5 GrantedAuthority
Представляет права пользователя (например, роли).

3. Установка и настройка Spring Security

Шаг 1: Подключение зависимостей
Для работы с Spring Security добавьте зависимости в pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>


Шаг 2: Настройка безопасности
Создайте класс конфигурации:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
)
.formLogin()
.and()
.logout();
return http.build();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}


Шаг 3: Настройка пользователей

Создайте пользователей в памяти для тестирования:
import org.springframework.context.annotation.Bean;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
public class InMemoryUserDetailsService {

@Bean
public UserDetailsService userDetailsService(PasswordEncoder passwordEncoder) {
UserDetails user = User.withUsername("user")
.password(passwordEncoder.encode("password"))
.roles("USER")
.build();

UserDetails admin = User.withUsername("admin")
.password(passwordEncoder.encode("admin"))
.roles("ADMIN")
.build();

return new InMemoryUserDetailsManager(user, admin);
}
}


4. Проверка безопасности

Запустите приложение и откройте в браузере:
/user — доступ только для пользователя с ролью USER или ADMIN.
/admin — доступ только для пользователя с ролью ADMIN.


#Java #Training #Spring #Security
Что выведет код?

import java.util.TreeSet;

public class Task101224_1 {
public static void main(String[] args) {
TreeSet<String> set = new TreeSet<>((s1, s2) -> s2.length() - s1.length());

set.add("one");
set.add("three");
set.add("four");
set.add("two");
set.add("five");

System.out.println(set);
}
}


#Tasks
Лучше б она ему биткоины купить предложила...🧐🤪

https://t.me/Java_for_beginner_dev

#Mems
В рамках дополнительной информации, устраняем пробел в знаниях по настройке поведения JVM.

Управление JVM (Java Virtual Machine) командами

Управление JVM (Java Virtual Machine) командами — это процесс конфигурации работы JVM через параметры, которые передаются при её запуске. Эти параметры позволяют настраивать поведение JVM, включая управление памятью, настройку сборщика мусора, логирование, отладку и безопасность. Все параметры JVM можно разделить на несколько категорий.

1. Основные типы параметров JVM

1.1. Стандартные параметры
Эти параметры поддерживаются всеми JVM и не зависят от конкретной реализации.

Например:
-cp или -classpath — указывает путь к классам и JAR-файлам.
-Dproperty=value — установка пользовательских системных свойств.
-version — выводит версию JVM.
-help — показывает справку по основным параметрам JVM.


Пример:
java -cp myapp.jar -Dconfig.file=app.properties com.example.Main


1.2. Параметры для настройки памяти

Эти параметры позволяют управлять распределением памяти в JVM:
-Xms<size> — начальный размер кучи (heap).
-Xmx<size> — максимальный размер кучи.
-Xss<size> — размер стека для каждого потока.
-XX:MetaspaceSize=<size> — начальный размер метапространства (метаданных классов).
-XX:MaxMetaspaceSize=<size> — максимальный размер метапространства.


Пример:
java -Xms512m -Xmx2g MyApp


1.3. Расширенные параметры (-X и -XX)

Эти параметры специфичны для реализации JVM (обычно HotSpot) и предоставляют дополнительные возможности:
-X параметры: упрощённые параметры, поддерживаемые большинством JVM.
-Xdebug — включает отладку.
-Xloggc:<file> — логирование работы сборщика мусора в файл.
-XX параметры: детальные настройки и эксперименты.
-XX:+UseG1GC — использование сборщика мусора G1.
-XX:ParallelGCThreads=<n> — количество потоков для параллельной сборки мусора.
-XX:+PrintGCDetails — выводит информацию о работе GC.
-XX:+HeapDumpOnOutOfMemoryError — создаёт дамп памяти при переполнении.


Пример:
java -XX:+UseG1GC -XX:+PrintGCDetails -XX:MaxHeapFreeRatio=70 MyApp


1.4. Логирование и диагностика

Эти параметры помогают анализировать производительность и поведение JVM:
-verbose:class — выводит информацию о загрузке классов.
-verbose:gc — выводит информацию о работе сборщика мусора.
-Xlog — гибкое управление логированием (начиная с Java 9).
Пример: -Xlog:gc* для логирования всех событий, связанных с GC.
-XX:+UnlockDiagnosticVMOptions — включает диагностические параметры.
Например: -XX:+PrintCompilation — выводит информацию о компиляции JIT.


Пример:
java -Xlog:gc* MyApp


1.5. Параметры безопасности
-Djava.security.manager — включает менеджер безопасности.
-Djava.security.policy=<file> — указывает путь к файлу политики безопасности.


2. Распределение памяти и работа GC

2.1. Память JVM

JVM делит память на несколько областей:
Heap (куча): для объектов.
Metaspace: для метаданных классов (начиная с Java 8).
Stack: для хранения вызовов методов и локальных переменных.
Native Memory: для работы JVM вне управляемой памяти.


2.2. Управление сборщиком мусора (GC)

Выбор GC сильно влияет на производительность:
-XX:+UseSerialGC — однопоточный сборщик мусора.
-XX:+UseParallelGC — многопоточный, ориентирован на максимальную пропускную способность.
-XX:+UseG1GC — G1 (Garbage-First) для больших приложений.
-XX:+UseZGC — Z Garbage Collector для низкой задержки (Java 11+).
-XX:+UseShenandoahGC — Shenandoah для низкой задержки (Java 12+).


3. Управление через команды операционной системы


Помимо параметров JVM, можно использовать команды ОС для управления процессом:
jps — список запущенных JVM.
jstat — статистика памяти и GC.
jmap — информация о памяти (heap dump).
jstack — вывод стека потоков.
jcmd — универсальный инструмент управления JVM.


4. Советы и рекомендации

Используйте флаги -Xlog вместо устаревших -verbose:gc в современных версиях Java.
Настройка памяти (-Xms и -Xmx) должна учитывать нагрузку приложения.
Анализируйте дампы памяти для отладки утечек.
Включайте диагностику (-XX:+UnlockDiagnosticVMOptions) только для тестирования.


#Java #Training #Medium #JVM_Commands
Основные принципы безопасности

Безопасность приложения должна обеспечиваться на всех уровнях — от архитектуры до шифрования данных.

1. Принципы обеспечения безопасности

1.1 Принцип наименьших привилегий
Каждый пользователь или система должны иметь минимальный набор разрешений, необходимый для выполнения своих задач.
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.anyRequest().authenticated()
);


1.2 Защита от атак CSRF
Spring Security по умолчанию включает защиту от CSRF.
CSRF — это атака, когда злоумышленник подделывает запрос от имени пользователя.

Можно настроить исключение для REST API:
http.csrf().disable();


1.3 Шифрование паролей
Пароли всегда должны храниться в зашифрованном виде. Используйте BCryptPasswordEncoder:
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}


1.4 Аудит и логирование
Всегда логируйте попытки доступа и события безопасности:
http.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin(form -> form
.successHandler((req, res, auth) -> System.out.println("Login success: " + auth.getName()))
.failureHandler((req, res, ex) -> System.out.println("Login failure: " + ex.getMessage()))
);


2. Шифрование данных

Используйте HTTPS для передачи данных между клиентом и сервером. Это защищает от перехвата данных в сети.

3. Проверка ввода и защита от XSS

Валидируйте входные данные и используйте механизмы защиты от XSS:
Применяйте фильтрацию данных.
Используйте HTML-энкодинг:

String safeContent = HtmlUtils.htmlEscape(unsafeContent);


Пример безопасного REST API с аутентификацией

Создадим REST API, который защищён с помощью JWT.

Шаг 1: Подключение зависимости:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>


Шаг 2: Генерация JWT-токена:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;

public class JwtUtil {

private static final String SECRET_KEY = "mySecretKey";

public static String generateToken(String username) {
return Jwts.builder()
.setSubject(username)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 60)) // 1 час
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}

public static boolean validateToken(String token, String username) {
String extractedUsername = Jwts.parser()
.setSigningKey(SECRET_KEY)
.parseClaimsJws(token)
.getBody()
.getSubject();
return username.equals(extractedUsername);
}
}


Шаг 3: Применение токена в безопасности:
@Configuration
public class JwtSecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.addFilter(new JwtAuthenticationFilter())
.sessionManagement().disable();
return http.build();
}
}


#Java #Training #Spring #Security #SecurityPrincipies
Spring Security и его интеграция в проект

Spring Security — это мощный и гибкий фреймворк для обеспечения безопасности приложений на базе Spring. Он предоставляет возможности для аутентификации, авторизации, защиты от атак CSRF, управления сессиями, защиты REST API и многого другого.

Шаг 1: Добавление Spring Security в проект

Для начала необходимо добавить зависимости Spring Security в ваш проект. В зависимости от того, используете ли вы Maven или Gradle, это можно сделать следующим образом:

Maven:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>


Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'


Шаг 2: Настройка Spring Security

Основные классы для настройки безопасности:
SecurityConfig — класс для настройки конфигурации безопасности.
UserDetailsService — сервис для работы с пользователями.
PasswordEncoder — компонент для кодирования паролей.


1. Конфигурация безопасности (Java-based)
Для настройки Spring Security создадим класс SecurityConfig, который будет аннотирован @Configuration и @EnableWebSecurity. Это обеспечит управление конфигурацией безопасности через Java-код.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable() // Отключение CSRF для упрощения тестирования
.authorizeHttpRequests((requests) -> requests
.requestMatchers("/public/**").permitAll() // Доступ для всех
.anyRequest().authenticated() // Остальные запросы требуют аутентификации
)
.formLogin((form) -> form
.loginPage("/login") // Кастомная страница логина
.permitAll()
)
.logout((logout) -> logout.permitAll());

return http.build();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Кодирование паролей
}
}


2. Реализация UserDetailsService
UserDetailsService используется для загрузки пользователей из хранилища данных (например, базы данных).

import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Collections;

@Service
public class CustomUserDetailsService implements UserDetailsService {

@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// Заглушка: обычно данные берутся из базы
if ("admin".equals(username)) {
return User.builder()
.username("admin")
.password("$2a$10$7b4/uWVqOKu8.cQeMEjCE.Oz7w9f5qL4uLcyuKkKJ7TzPByHOfy92") // Закодированный "password"
.roles("ADMIN")
.build();
} else {
throw new UsernameNotFoundException("Пользователь не найден");
}
}
}


#Java #Training #Spring #Security #AddSecurity
Пароль можно закодировать с помощью следующего кода:
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

public class PasswordEncoderTest {
public static void main(String[] args) {
BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
String rawPassword = "password";
String encodedPassword = encoder.encode(rawPassword);
System.out.println(encodedPassword);
}
}


3. Кастомизация страницы логина
Для создания кастомной страницы логина добавьте следующий контроллер:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class LoginController {

@GetMapping("/login")
public String login() {
return "login"; // Вернет login.html
}
}


Создайте шаблон login.html:


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Login</title>
</head>
<body>
<h2>Login Page</h2>
<form th:action="@{/login}" method="post">
<label for="username">Username:</label>
<input type="text" id="username" name="username"/><br>
<label for="password">Password:</label>
<input type="password" id="password" name="password"/><br>
<button type="submit">Login</button>
</form>
</body>
</html>


#Java #Training #Spring #Security #AddSecurity
Что выведет код?

class Animal1112 {
void sound() {
System.out.println("Animal makes a sound");
}
}

class Dog1112 extends Animal1112 {
@Override
void sound() {
System.out.println("Dog barks");
}

void fetch() {
System.out.println("Dog fetches a ball");
}
}

class Cat1112 extends Animal1112 {
@Override
void sound() {
System.out.println("Cat meows");
}
}

public class Task111224_1 {
public static void main(String[] args) {
Animal1112 animal1 = new Dog1112();
Animal1112 animal2 = new Cat1112();
animal1.sound();
animal2.sound();

if (animal1 instanceof Dog1112) {
((Dog1112) animal1).fetch();
}

if (animal2 instanceof Dog1112) {
((Dog1112) animal2).fetch();
} else {
System.out.println("Not a Dog");
}
}
}


#Tasks
Ну так это ж девопс😂

https://t.me/Java_for_beginner_dev

#Mems
Продолжаем устранять пробелы по управлению JVM командами.

1. Компиляция программ Java

Для компиляции используется команда javac, которая превращает исходный код (.java) в байт-код (.class).

1.1. Основной синтаксис

javac [опции] <файлы.java>


1.2. Основные параметры
-d <директория> — указывает каталог для выходных файлов .class.
javac -d out src/com/example/MyClass.java


-classpath или -cp — задаёт путь к используемым классам и библиотекам.
javac -cp libs/mylib.jar MyProgram.java


-source <версия> — задаёт версию языка Java для исходного кода.
javac -source 11 MyProgram.java


-target <версия> — указывает целевую версию JVM, для которой будет скомпилирован байт-код.

javac -source 11 -target 8 MyProgram.java


-encoding <кодировка> — кодировка исходных файлов (например, UTF-8).
javac -encoding UTF-8 MyProgram.java


-verbose — выводит дополнительную информацию о процессе компиляции.

2. Запуск программы

Для запуска скомпилированного кода используется команда java, которая запускает JVM и исполняет байт-код.

2.1. Основной синтаксис
java [опции] <имя_класса> [аргументы]


2.2. Основные параметры
-classpath или -cp — задаёт путь к классам и библиотекам.
java -cp out:libs/mylib.jar com.example.MyClass


-D<ключ>=<значение> — задаёт системное свойство, доступное через System.getProperty().
java -Dconfig.file=app.properties com.example.MyClass


-X и -XX параметры — для настройки JVM (управление памятью, GC и т.д.).
--enable-preview — включает поддержку экспериментальных функций (начиная с Java 12).

Пример запуска:
java -Xmx2g -cp out:libs/mylib.jar com.example.MainClass arg1 arg2


3. Утилиты для работы с классами

3.1. jar
Утилита для создания, просмотра и распаковки JAR-архивов.

3.1.1. Создание JAR-файла
jar cf myapp.jar -C out .


Здесь:
c — создать JAR.
f — имя выходного файла.
-C <путь> — указать корневую директорию классов.


3.1.2. Просмотр содержимого JAR
jar tf myapp.jar


3.1.3. Добавление манифеста

Манифест определяет точку входа в приложение:
jar cfe myapp.jar com.example.MainClass -C out .


Флаг e указывает класс с методом public static void main(String[] args).

3.2. javadoc
Генерация HTML-документации из Java-комментариев.

Пример:
javadoc -d docs -sourcepath src -subpackages com.example


3.3. javap
Дизассемблер для классов Java.

Пример:
javap -c com.example.MyClass


Флаг -c выводит байт-код методов.

3.4. jdeps
Инструмент для анализа зависимостей классов.

Пример:
jdeps -summary myapp.jar


4. Утилиты для анализа и отладки

4.1. jdb
Отладчик Java. Используется для пошаговой отладки приложения.

Пример запуска:
jdb -classpath out com.example.MainClass


Команды внутри jdb:
stop at com.example.MainClass:15 — установить точку останова на 15-й строке.
run — запустить программу.
step — выполнить следующую строку.


4.2. Инструменты мониторинга JVM
jps — выводит список всех работающих JVM.
jps -v


jstat — статистика памяти и GC.
jstat -gc <pid>


jmap — информация о памяти, снимки heap.
jmap -heap <pid>


jstack — вывод стека потоков.
jstack <pid>


jcmd — универсальная утилита управления JVM.
jcmd <pid> VM.uptime


5. Пример полного цикла работы

Компиляция:
javac -d out -sourcepath src src/com/example/MainClass.java


Создание JAR:
jar cfe myapp.jar com.example.MainClass -C out .


Запуск:
java -cp myapp.jar com.example.MainClass


Мониторинг:
jps
jstat -gc <pid>
jmap -heap <pid>


#Java #Training #Medium #JVM_Commands
Аннотации используемые в Spring Security

1. @EnableWebSecurity

Аннотация @EnableWebSecurity включает поддержку безопасности на уровне веб-приложений. Она сигнализирует Spring, что текущий класс является конфигурацией безопасности, и подготавливает инфраструктуру Spring Security.

Пример:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;

@Configuration
@EnableWebSecurity
public class SecurityConfig {
// Здесь будут методы настройки безопасности
}


Нюансы:
Без этой аннотации конфигурация безопасности не будет применена.
Аннотация автоматически активирует SpringSecurityFilterChain.


2. @Configuration

Используется для указания, что класс содержит настройки и бины Spring Security.

Пример:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

@Configuration
public class SecurityConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}


Нюансы:
Это аннотация общего назначения, используется в любой конфигурации Spring, включая Spring Security.
Ее можно комбинировать с
@EnableWebSecurity.

3.
@PreAuthorize

Аннотация @PreAuthorize позволяет выполнять проверку безопасности перед выполнением метода. Условие определяется с помощью SpEL (Spring Expression Language).

Пример:
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;

@Service
public class UserService {

@PreAuthorize("hasRole('ADMIN')")
public void adminOnlyMethod() {
System.out.println("Только для администраторов");
}

@PreAuthorize("#username == authentication.principal.username")
public void userSpecificMethod(String username) {
System.out.println("Только для пользователя: " + username);
}
}


Нюансы:
Требует включения аннотаций на уровне метода: добавьте @EnableGlobalMethodSecurity(prePostEnabled = true) в класс конфигурации.
Поддерживает сложные выражения SpEL.


4. @PostAuthorize

Выполняет проверку безопасности после выполнения метода. Это полезно, если доступ к результату должен зависеть от данных, возвращенных методом.

Пример:
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.stereotype.Service;

@Service
public class ProductService {

@PostAuthorize("returnObject.owner == authentication.principal.username")
public Product getProductById(Long id) {
// Имитируем возврат продукта
return new Product(id, "username123");
}
}

class Product {
public Long id;
public String owner;

public Product(Long id, String owner) {
this.id = id;
this.owner = owner;
}
}


Нюансы:
Используется реже, так как может повлиять на производительность из-за выполнения после обработки.
Требует
@EnableGlobalMethodSecurity(prePostEnabled = true).

5. @Secured

Аннотация @Secured ограничивает доступ к методам на основе ролей. В отличие от @PreAuthorize, она не поддерживает SpEL.

Пример:
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;

@Service
public class ReportService {

@Secured("ROLE_ADMIN")
public void generateAdminReport() {
System.out.println("Отчет для администратора");
}

@Secured({"ROLE_USER", "ROLE_MANAGER"})
public void generateUserReport() {
System.out.println("Отчет для пользователя или менеджера");
}
}


Нюансы:
Для использования @Secured необходимо включить метод-базированную безопасность:
@EnableGlobalMethodSecurity(securedEnabled = true)


Роли должны быть указаны с префиксом ROLE_.

#Java #Training #Spring #Security #Security_Annotations
6. @WithMockUser

Используется для создания фиктивного пользователя при тестировании.

Пример:

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.test.context.support.WithMockUser;

@SpringBootTest
public class MyServiceTest {

@Test
@WithMockUser(username = "testUser", roles = {"USER"})
public void testUserAccess() {
// Тестовый метод, где выполняется проверка с фиктивным пользователем
System.out.println("Тест с пользователем testUser");
}
}


Нюансы:
Используется только в тестах.
Можно указывать пользователя, роли и пароль для эмуляции различных ситуаций.


7. @EnableGlobalMethodSecurity

Эта аннотация включает поддержку аннотаций на уровне методов, таких как @PreAuthorize, @PostAuthorize, @Secured.

Пример:
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class MethodSecurityConfig {
}


Нюансы:
Параметры:
prePostEnabled — включает
@PreAuthorize и @PostAuthorize.
securedEnabled — включает
@Secured.
jsr250Enabled — включает аннотации JSR-250 (
@RolesAllowed).

8. @RolesAllowed

Это аннотация стандарта JSR-250, которая ограничивает доступ к методам на основе ролей.

Пример:
import jakarta.annotation.security.RolesAllowed;
import org.springframework.stereotype.Service;

@Service
public class OrderService {

@RolesAllowed("ROLE_USER")
public void userMethod() {
System.out.println("Метод для пользователей");
}
}


Нюансы:
Требует включения в конфигурации:
@EnableGlobalMethodSecurity(jsr250Enabled = true)


9. @CrossOrigin

Эта аннотация позволяет настройку CORS (Cross-Origin Resource Sharing).

Пример:
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ApiController {

@CrossOrigin(origins = "http://example.com")
@GetMapping("/data")
public String getData() {
return "Data from server";
}
}


Нюансы:
Применима для REST API для указания разрешенных доменов.

#Java #Training #Spring #Security #Security_Annotations
Аутентификация и Авторизация в Spring Security

1. Основные Концепции

1.1 Аутентификация
Аутентификация — это процесс проверки подлинности пользователя. В Spring Security это обычно достигается с использованием имени пользователя и пароля, хотя возможны и другие подходы (JWT, OAuth2 и т.д.).

Основные компоненты аутентификации:
AuthenticationManager: Интерфейс, который определяет стратегию аутентификации.
AuthenticationProvider: Обрабатывает аутентификацию для конкретного типа данных (например, база данных, LDAP).
UserDetailsService: Загрузка пользователя по имени.
PasswordEncoder: Кодирует и проверяет пароли.


1.2 Авторизация
Авторизация — это процесс проверки, имеет ли пользователь право на выполнение определенных действий. В Spring Security это достигается с использованием ролей и разрешений.

Основные компоненты авторизации:
SecurityContextHolder: Хранит данные о текущем пользователе.
AccessDecisionManager: Принимает решение о доступе.
GrantedAuthority: Представляет роль или право.


2. Настройка Аутентификации и Авторизации

2.1 Добавление Зависимостей
Для начала необходимо добавить зависимости Spring Security в проект.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>


Gradle:
implementation 'org.springframework.boot:spring-boot-starter-security'


2.2 Настройка Конфигурации Безопасности

Создадим класс конфигурации, используя Java-based настройку:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
@EnableWebSecurity
public class SecurityConfig {

@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf().disable() // Отключение CSRF для упрощения
.authorizeHttpRequests(auth -> auth
.requestMatchers("/public/**").permitAll() // Доступ к публичным ресурсам
.requestMatchers("/admin/**").hasRole("ADMIN") // Доступ только для ADMIN
.anyRequest().authenticated() // Остальные запросы требуют аутентификации
)
.formLogin(form -> form
.loginPage("/login") // Кастомная страница логина
.permitAll()
)
.logout(logout -> logout
.permitAll()
);

return http.build();
}

@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(); // Для кодирования паролей
}

// Пример встроенной аутентификации
@Bean
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user")
.password(passwordEncoder().encode("password"))
.roles("USER")
.and()
.withUser("admin")
.password(passwordEncoder().encode("admin"))
.roles("ADMIN");
}
}


#Java #Training #Spring #Security #Security_Authentication #Security_Authority