본문 바로가기

개발기술/Java

Java Dependency - Marven, Gradle, exteral libraries(Lombok etc)

Dependency

  • Adding a dependency refers to including external libraries or modules that your project requires to function correctly. In the context of Java projects, dependencies are often managed using build tools like Maven or Gradle. These tools help automate the process of downloading, configuring, and managing the libraries your project needs.
    • Maven is a build automation tool used primarily for Java projects. It uses a pom.xml (Project Object Model) file to manage project dependencies, build configurations, and project metadata.
    • Gradle is another popular build automation tool for Java and other languages. It uses a build.gradle file to manage dependencies and project configurations.

 

Marven

  • Role of maven
    • Project Object Model (POM) : The pom.xml file is the core of a Maven project. It contains information about the project and configuration details (which are included below)
    • Dependency Management : Maven automatically handles the downloading and inclusion of project dependencies. This ensures that all required libraries are available for the build process.
    • Build Lifecycle: Maven defines a standard build lifecycle, which includes phases like validate, compile, test, package, verify, install, and deploy.
      • validate: Validate the project is correct and all necessary information is available.
      • compile: Compile the source code of the project.
      • test: Test the compiled source code using a suitable testing framework.
      • package: Package the compiled code into a distributable format (e.g., JAR, WAR).
      • verify: Run any checks to verify the package is valid and meets quality criteria.
      • install: Install the package into the local repository for use as a dependency in other projects.
      • deploy: Copy the final package to a remote repository for sharing with other developers and projects.
    • Plugins:Maven's functionality is extended through plugins. Plugins perform tasks such as compiling code, running tests, packaging code, generating documentation, and more.
    • Project Structure: Maven enforces a standard directory layout, which helps in maintaining a consistent project structure across multiple projects. (dividing directory layout into java, resources, test, myapp, target etc
    •  Profiles Build Settings: Defining the Java version, source and target directories, and packaging options,  Profiles: Creating different configurations for different environments (e.g., development, testing, production) 
    • Repositories:  Configuring where Maven should look for dependencies (e.g., local, central, custom repositories)
    • Build and Reporting Tools:Maven integrates with various reporting tools to generate project documentation, including code coverage reports, test results, and static code analysis reports.
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!-- Project coordinates -->
    <groupId>com.example</groupId>
    <artifactId>myapp</artifactId>
    <version>1.0-SNAPSHOT</version>

    <!-- Project metadata -->
<name>My Application</name>
<description>A simple application using Maven</description>
    <url>http://www.example.com/myapp</url>

    <!-- Dependencies -->
    <dependencies>
        <!-- Example of a dependency -->
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>3.0.3</version>
        </dependency>
    </dependencies>

    <!-- Build settings -->
    <build>
        <plugins>
            <!-- Example of a plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

 

  • pom.xml Structure :  The pom.xml (Project Object Model) file is the heart of a Maven project. It contains information about the project and configuration details used by Maven to build the project`.
    • <project>: This is the root element of a Maven pom.xml file.
    • xmlns, xmlns:xsi, xsi:schemaLocation: These attributes define the XML namespace and schema location. They ensure the XML content conforms to the Maven POM schema
    • <modelVersion>: Specifies the version of the POM model. For almost all modern Maven projects, this is 4.0.0.
    • <groupId>: A unique identifier for the project group or company. This typically follows a reversed domain name convention (e.g., com.example).
    • <artifactId>: A unique name for the project within the group. This is usually the name of the project or module.
    • <version>: The version of the project. A -SNAPSHOT suffix indicates that this is a development version, and Maven can update the snapshot versions automatically.

 

Gradle

Gradle is a powerful build automation tool that is primarily used for Java projects.

build.gradle 파일내에 dependency를 설정해주면 됨.

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.3.2'
    id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    runtimeOnly 'com.h2database:h2'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    // redis client
    implementation 'org.redisson:redisson:3.17.1'
    // embedded redis
    implementation('it.ozimov:embedded-redis:0.7.3') {
        exclude group: "org.slf4j", module: "slf4j-simple"
    }
}

tasks.named('test') {
    useJUnitPlatform()
}

 

Gradle Wrapper

The Gradle Wrapper (often called gradlew) is a script that invokes a declared version of Gradle, downloading it beforehand if necessary. This means you don’t need to have Gradle installed to build your project, which ensures that everyone who builds the project will use exactly the same version of Gradle,

 

 

DeepDive into Gradle

How Gradle Works

1. Initialization

Think of this as the "setup" phase. When you run Gradle, the very first thing it does is look at your project to understand its structure and requirements. Here's what happens:

  • Detecting Projects: If your project is part of a bigger group of projects (a multi-project build), Gradle identifies all the different parts it needs to manage. (settings.gradle, Project Directory Structure)
  • Setting Up Environment: Gradle checks your settings files (like settings.gradle) to figure out where everything is located and any special configurations that might affect the build.

2. Configuration

In this phase, Gradle reads through your build scripts (written in Groovy or Kotlin DSL, build.gradle). These scripts tell Gradle what needs to be done but don’t actually do anything yet. Here's what's going on:

  • Reading Scripts: Gradle goes through the build scripts where tasks are defined (like compiling code, copying files, etc.).
  • Organizing Tasks: It organizes these tasks based on what they depend on.
  • Setting Properties: Gradle also sets properties and configurations that the tasks will use later during the execution phase.

3. Execution of Build Configuration

Now, Gradle actually starts doing the work. This is the "action" phase. Here's what happens:

  • Task Execution: Gradle starts running the tasks that were set up during the configuration phase. It follows the order based on dependencies between tasks.
  • Incremental Builds: Gradle checks to see if anything has changed since the last build. If some files haven't changed, it won’t redo work related to those files. This saves time.
  • Parallel Execution: If possible, Gradle will run independent tasks at the same time to speed up the build process.

Gradle Output

  • .gradle directory
    • Purpose: This directory is used by Gradle itself to store project-specific configuration settings and caches.
    • Contents: It typically contains cached Gradle tasks outputs, scripts, and other internal data that Gradle uses to optimize build performance and ensure that incremental builds work correctly.
  • build directory
    • Purpose: This is the default directory where Gradle stores all outputs from the build process.
    • Contents: Compiled classes, processed resources, generated documentation, and packaged artifacts (e.g., JAR files), along with testing and reports data.

Debugging dependency Conflict

 

dependency 정보확인하기

1.View Dependency Tree: Run gradle dependencies to see the entire dependency tree.

인텔리제에서 우측 gradle 버튼을 누르면, dependency tree가 나타나고 conflict나 import되지 않은 dependency 확인가능함.

2. init되는 dependency는 로그를 통해서 버전을 확인할 수 있음.

 

 

build

  • Purpose: This is the default directory where Gradle stores all outputs from the build process.

 

 

외부 Dependency 소개

JDBC 라이브러리

  • JDBC (Java Database Connectivity) is an API (Application Programming Interface) in Java that defines how clients may access a database 
  • 설치 
    • 아래의 dependency 정보를 pom.xml파일에 입력하고, 인텔리제의 xml파일에서 오른쪽 버튼 클릭 - maven - 프로젝트 리로트를 클릭시 해당 라이브러리가 설치됨
    • 라이브러리 설치를 재확인하기 위해서 build tap - rebuild를 선택.
<dependency>
           <groupId>org.mariadb.jdbc</groupId>
           <artifactId>mariadb-java-client</artifactId>
           <version>3.0.3</version>
       </dependency>

 

  • spring-boot-starter-data-jpa : JPA(Java Persistence API) 지원
  • spring-boot-starter-validation : bean validation 지원
  • spring-boot-starter-web : Spring Web(API) 개발을 위한 지원
  • org.redisson:redisson : redisson이라는 redis를 이용한 분산락을 지원하는 client
  • it.ozimov:embedded-redis : 임베디드 reids

 

Lombok

  • 자바의 보일러 플레이트 코드를 줄여주는 라이브러리
  • @Setter, @Getter : Java Bean 규악에 있는 setter, getter를 자동생성
  • @ToString : Object 기본 구현된 ToString대신 객체의 데이터를 보여주는 ToString을 자동생성
  • @NoArgsConstructor : 객체 생성자를 자동생성하며 모든 field를 설정하지 않아도 생성하도록 함. Builder pattern에서 필요.
  • @AllArgsConstructor : 객체 생성자를 자동생성, 모든 field를 설정하거나, . 특정 라이브러리에서 요구하여 사용함.
  • @RequiredArgsConstructor : Final로 표시된 field를 모두 생성토록하며 @notnull로 제약처리를 함, autowired를 시키기 위해서는 private final을 포함하는 생성자가 필요한데 그때 사용됨.
  • @Data : Getter, Setter, ToString, Equals, hashCode 등 다양한 기능을 한번에 다 합쳐서 제공
    • 그러나 민감한 정보의 경우에는 toString이나 equals기능으로 정보가 노출되면 안되기 때문에 @Data는 실무적으로 많이 쓰이지 않는다. 
  • @Equals : 기본적으로 equals는 객체의 주소를 비교하게 되는데, method overriding을 통해서 객체의 타입과 필드가 같으면 true를 반환하도록 함
  • @Hashcode : 위의 @equals로 동일한 값을 갖는 object는 hashcode 역시 동일하도록 로직을 변경해줌 그리하여 hashset, hashmap에서 동일한 객체로 인식되도록.
  • @Builder : 빌더패턴(디자인 패턴 중 일환)을 자동으로 제공
    • 빌더패턴 : 클래스 내부에 static 메소드 builder() 를 통해서 static 내부클래스 class.classbuilder를 생성함. 그리고 이 classbuilder의 필드들의 값을 setter를 통해서 하나씩 받고서 마지막으로 static 메소드 build() 메소드로 allargsconstructor을 발송시킴
  • @Slf4j : 해당 클래스의 logger를 자동생성
    • log라는 field를 따로 만들지 않아도 해당 클래스를 input값으로 해서 log instance를 갖는 field를 만들어줌. 하여, log.method 기능을 사용할 수 있음.
  • @UtilityClass : static method만 제공하는 유틸리티 성격의 클래스들의 생성자를  private으로 만들어 객체를 생성할수 없도록 함. 
     
     
  • Lombok and Spring when to use
    •  @NoArgsConstructor
      • Entity Instantiation by JPA: JPA requires a no-argument constructor to create entities when fetching from the database. This is fundamental for any JPA entity.
      • Deserialization: When your application needs to deserialize data (e.g., from JSON using Jackson), a no-argument constructor is necessary. This is common in RESTful APIs where you receive JSON data that needs to be converted into Java objects.
      • Spring Beans: Sometimes, Spring's dependency injection and other frameworks require no-arg constructors for proxy creation and other internal uses.
      • Considerations:
      • Default Values: Use this when it's acceptable for the object to have uninitialized fields with default values (like null for objects, 0 for int, etc.), which will later be set using setters or field access.
    •   @AllArgsConstructor
      • Immutable Classes: For creating immutable classes where all fields are initialized via the constructor and no setters are provided. This ensures that the object state cannot change after its creation, which is beneficial for thread-safety and consistency.
      • Fully Populated Objects: When you need to ensure that an object is fully populated at creation, preventing any fields from being uninitialized.
      • Testing and Convenience: Useful in tests and when manually creating instances of classes without relying on frameworks like Spring for dependency injection.
      • Overhead with Many Fields: With a large number of fields, constructors generated by @AllArgsConstructor can become unwieldy and hard to manage or read.
    •  @RequiredArgsConstructor
      • Mandatory Fields: When certain fields in your classes are essential for the object’s operation and must be initialized upon object creation. This is common with final fields or fields annotated with @NonNull, ensuring that critical dependencies are not missing.
      • Spring Component Injection: Ideal for Spring services or components where specific dependencies must be injected by Spring. This helps in ensuring that these dependencies are provided at the time of bean instantiation.
      • Flexibility: It offers a middle ground between @NoArgsConstructor and @AllArgsConstructor by only requiring arguments for essential fields, thus providing more flexibility than @AllArgsConstructor while ensuring more safety than @NoArgsConstructor.

 

'개발기술 > Java' 카테고리의 다른 글

Deep Dive into 디버깅  (2) 2024.09.15
Java 쓰레드 관리  (0) 2024.08.12
Java 언어의 이해  (0) 2024.06.19
Java 코딩구현 - I/O System  (1) 2024.06.14
Java 코딩구현 기초 - 데이터타입  (0) 2024.05.22