in rus
https://struchkov.dev/blog/ru/exception-handling-controlleradvice/
validation handling
STARTER
let’s create some new module and infra package in it
package infra;
public class SomeInfraBean {
public void sayHello() {
System.out.println("hello from infra bean");
}
}
package infra;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SomeInfraConfiguration {
@Bean
public SomeInfraBean someInfraBean() {
return new SomeInfraBean();
}
}
plugins {
id("java")
id("org.springframework.boot") version "3.2.4"
id("io.spring.dependency-management") version "1.1.4"
}
group = "org.example"
version = "unspecified"
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
testImplementation(platform("org.junit:junit-bom:5.9.1"))
testImplementation("org.junit.jupiter:junit-jupiter")
}
tasks.test {
useJUnitPlatform()
}
//val jar: Jar by tasks
//val bootJar: BootJar by tasks
//
//bootJar.enabled = false
//jar.enabled = true
//
//
//tasks.getByName<BootJar>("bootJar") {
// enabled = false
//}
//
//tasks.getByName<Jar>("jar") {
// enabled = true
//}
MAIN APP
in main app we can call and use this bean like this
import infra.SomeInfraBean;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class SomeService {
@Autowired
private SomeInfraBean someInfraBean;
@PostConstruct
public void testInfrabean() {
someInfraBean.sayHello();
}
@Value("${mymessage}")
private void init(String msg) {
System.out.println(msg);
}
}
package com.stanley.borisovSpringDeep.circularDependency;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Main {
}
a couple of classes with business logic
Continue readingAny beanFactoryPostProcessor should be declared in @Configuration file with static, because configuration is being initialized in very begining.
Nothing needed, props a read from application.properties / application.yml file, but if you want to custmomize the file you can add annotation
@PropertySource("myapplication.properties")
Also we can use PropertySourcesPlaceholderConfigurer
By default we can read from resources/application.properties file, but we also can configure another one like this
create file myapplication.properties
mymessage=hello from app properties
configure spring
@Configuration
@PropertySource("myapplication.properties")
public class Config {
@Bean
public PropertySourcesPlaceholderConfigurer configurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
call mymessage from someService
@Service
public class SomeService {
@Value("${mymessage}")
private void init(String msg) {
System.out.println(msg);
}
}
and here we are
Also @ApplicationProperties can be used
Find the reference to Spring Framework in the build.gradle file in the source for that Spring Boot version in GitHub.
For example, from the build.gradle for Spring Boot 2.6.6:
library("Spring Framework", "5.3.18")
another way
Here is a quick way to find which version of spring-core is used.
Google “spring-boot-starter-test”.
Click on the first link that comes back - spring-boot-starter-test on mvnrepository
Click in the version of interest, eg 2.6.6
Find the spring-core dependency: 5.3.18
Commands
// rebuild some service in docker compose
docker-compose up -d --no-deps --build recognition-server
// start all containers in docker compose
docker-compose up
// down all containers
docker-compose down
Files
Dockerfile
FROM eclipse-temurin:17.0.10_7-jdk-jammy
MAINTAINER stanley_ekb
COPY ../build/libs build/libs
ENTRYPOINT ["java","-jar","build/libs/recognition-0.0.1-SNAPSHOT.jar", "sber.recognition.App", "-cp", "foodVision.recognition.main", "--server.port=2077"]
docker-compose.yml
version: '3'
services:
recognition-server:
container_name: recognition-server
build:
context: ../recognition
dockerfile: ./docker/Dockerfile
image: recognition-server:latest
ports:
- 2077:2077
# networks:
# - spring-cloud-network
zookeeper:
image: confluentinc/cp-zookeeper:latest
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
restart: unless-stopped
ports:
- "22181:2181"
kafka:
image: confluentinc/cp-kafka:latest
container_name: kafka
depends_on:
- zookeeper
restart: unless-stopped
ports:
- "9092:9092"
- "29092:29092"
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
docker-compose.yml
version: '3'
services:
zookeeper:
image: confluentinc/cp-zookeeper:latest
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
restart: unless-stopped
ports:
- "22181:2181"
kafka:
image: confluentinc/cp-kafka:latest
container_name: kafka
depends_on:
- zookeeper
restart: unless-stopped
ports:
- "9092:9092"
- "29092:29092"
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
go to the directory of file and type
docker-compose up
kafka container console
docker exec -it kafka /bin/bash
create topic
kafka-topics --create --topic myfirstTopic --partitions 1 --bootstrap-server localhost:9092
list all topics
kafka-topics --list --bootstrap-server localhost:9092
writing to topic
kafka-console-producer --broker-list localhost:9092 --topic myfirstTopic
reading wrom topic
kafka-console-consumer --bootstrap-server localhost:9092 --topic myfirstTopic --from-beginning
// first of all disable mySql Service if it was installed before or you will receive error like this
Lost connection to MySQL server at 'reading initial communication packet', system error: 0
// start docker container on 3307 port
docker run --name mysqlContainer -p 3307:3307 -e MYSQL_ROOT_PASSWORD=root -e MYSQL_ROOT_HOST=% -d mysql:latest
// connect to mysql monitor
mysql -h localhost -P 3307 -u root -proot
// bash inside docker
docker exec -it mysql bash
ignoring cache and refreshes the dependencies
./gradlew --refresh-dependencies
./gradlew resolveAndLockAll --write-locks