Skip to content

项目结构

本指南介绍 LCGYL Framework 项目的标准目录结构和组织方式。

标准项目结构

基础结构

my-app/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/
│   │   │       └── example/
│   │   │           └── myapp/
│   │   │               ├── Application.java          # 主应用类
│   │   │               ├── config/                   # 配置类
│   │   │               ├── controller/               # 控制器(Web)
│   │   │               ├── service/                  # 业务逻辑
│   │   │               ├── repository/               # 数据访问
│   │   │               ├── model/                    # 领域模型
│   │   │               ├── dto/                      # 数据传输对象
│   │   │               ├── event/                    # 事件定义
│   │   │               ├── listener/                 # 事件监听器
│   │   │               └── util/                     # 工具类
│   │   └── resources/
│   │       ├── application.properties                # 主配置文件
│   │       ├── application-dev.properties            # 开发环境配置
│   │       ├── application-prod.properties           # 生产环境配置
│   │       ├── logback.xml                          # 日志配置
│   │       └── static/                              # 静态资源
│   └── test/
│       ├── java/
│       │   └── com/
│       │       └── example/
│       │           └── myapp/
│       │               ├── service/                  # 服务测试
│       │               ├── repository/               # 数据访问测试
│       │               └── integration/              # 集成测试
│       └── resources/
│           └── application-test.properties           # 测试配置
├── build.gradle                                      # Gradle 构建文件
├── settings.gradle                                   # Gradle 设置
├── README.md                                         # 项目说明
└── .gitignore                                        # Git 忽略文件

目录说明

源码目录 (src/main/java)

Application.java - 主应用类

应用的入口点,负责启动框架。

java
package com.example.myapp;

import com.lcgyl.core.application.LcgylApplication;
import com.lcgyl.core.application.annotation.ComponentScan;

@ComponentScan("com.example.myapp")
public class Application {
    
    public static void main(String[] args) {
        LcgylApplication app = LcgylApplication.run(Application.class, args);
        System.out.println("应用启动成功!");
    }
}

config/ - 配置类

存放应用配置相关的类。

java
package com.example.myapp.config;

import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.framework.core.annotation.Value;

@Component
public class AppConfig {
    
    @Value("app.name")
    private String appName;
    
    @Value("app.version")
    private String version;
    
    // Getters
}

controller/ - 控制器

处理 HTTP 请求(Web 应用)。

java
package com.example.myapp.controller;

import com.lcgyl.web.annotation.RestController;
import com.lcgyl.web.annotation.GetMapping;
import com.lcgyl.framework.core.annotation.Inject;

@RestController("/api/users")
public class UserController {
    
    @Inject
    private UserService userService;
    
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.findById(id);
    }
}

service/ - 业务逻辑

包含应用的核心业务逻辑。

java
package com.example.myapp.service;

import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.framework.core.annotation.Inject;

@Component
public class UserService {
    
    @Inject
    private UserRepository userRepository;
    
    @Inject
    private EventBus eventBus;
    
    public User createUser(String name) {
        User user = new User(name);
        userRepository.save(user);
        eventBus.publish(new UserCreatedEvent(user));
        return user;
    }
    
    public User findById(Long id) {
        return userRepository.findById(id);
    }
}

repository/ - 数据访问

负责数据持久化操作。

java
package com.example.myapp.repository;

import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.data.annotation.Repository;

@Component
@Repository
public class UserRepository {
    
    @Inject
    private JdbcTemplate jdbcTemplate;
    
    public User findById(Long id) {
        String sql = "SELECT * FROM users WHERE id = ?";
        return jdbcTemplate.queryForObject(sql, User.class, id);
    }
    
    public void save(User user) {
        String sql = "INSERT INTO users (name, email) VALUES (?, ?)";
        jdbcTemplate.update(sql, user.getName(), user.getEmail());
    }
}

model/ - 领域模型

定义业务实体。

java
package com.example.myapp.model;

public class User {
    private Long id;
    private String name;
    private String email;
    
    // 构造器、Getters、Setters
}

dto/ - 数据传输对象

用于 API 请求和响应。

java
package com.example.myapp.dto;

public record UserRequest(String name, String email) {
}

public record UserResponse(Long id, String name, String email) {
}

event/ - 事件定义

定义应用事件。

java
package com.example.myapp.event;

import com.lcgyl.framework.core.event.Event;

public record UserCreatedEvent(User user) implements Event {
}

listener/ - 事件监听器

处理应用事件。

java
package com.example.myapp.listener;

import com.lcgyl.framework.core.annotation.Component;
import com.lcgyl.framework.core.event.Subscribe;

@Component
public class UserEventListener {
    
    @Subscribe
    public void onUserCreated(UserCreatedEvent event) {
        System.out.println("用户创建:" + event.user().getName());
    }
}

util/ - 工具类

通用工具方法。

java
package com.example.myapp.util;

public class StringUtils {
    
    public static boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }
}

资源目录 (src/main/resources)

application.properties - 主配置文件

properties
# 应用配置
app.name=MyApp
app.version=1.0.0

# 服务器配置
server.port=8080
server.host=localhost

# 数据库配置
datasource.url=jdbc:mysql://localhost:3306/myapp
datasource.username=root
datasource.password=password

# 日志配置
logging.level.root=INFO
logging.level.com.example.myapp=DEBUG

application-dev.properties - 开发环境

properties
# 开发环境配置
server.port=8080
datasource.url=jdbc:mysql://localhost:3306/myapp_dev
logging.level.root=DEBUG

application-prod.properties - 生产环境

properties
# 生产环境配置
server.port=80
datasource.url=jdbc:mysql://prod-db:3306/myapp
logging.level.root=WARN

logback.xml - 日志配置

xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/app.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>

测试目录 (src/test/java)

单元测试

java
package com.example.myapp.service;

import org.testng.annotations.Test;
import org.testng.annotations.BeforeMethod;
import static org.testng.Assert.*;
import static org.mockito.Mockito.*;

public class UserServiceTest {
    
    private UserService userService;
    private UserRepository userRepository;
    
    @BeforeMethod
    public void setUp() {
        userRepository = mock(UserRepository.class);
        userService = new UserService(userRepository);
    }
    
    @Test
    public void testFindById() {
        // Given
        User user = new User(1L, "张三");
        when(userRepository.findById(1L)).thenReturn(user);
        
        // When
        User result = userService.findById(1L);
        
        // Then
        assertNotNull(result);
        assertEquals(result.getName(), "张三");
    }
}

集成测试

java
package com.example.myapp.integration;

import org.testng.annotations.Test;
import com.lcgyl.core.application.LcgylApplication;

public class ApplicationIntegrationTest {
    
    @Test
    public void testApplicationStartup() {
        LcgylApplication app = LcgylApplication.run(Application.class);
        assertNotNull(app);
        app.stop();
    }
}

构建文件

build.gradle

gradle
plugins {
    id 'java'
    id 'application'
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '21'

repositories {
    mavenCentral()
}

dependencies {
    // LCGYL Framework
    implementation 'com.lcgyl:lcgyl-framework-core:2.2.0'
    implementation 'com.lcgyl:lcgyl-web-plugin:2.2.0'
    implementation 'com.lcgyl:lcgyl-data-plugin:2.2.0'
    
    // 日志
    implementation 'org.slf4j:slf4j-api:2.0.9'
    runtimeOnly 'ch.qos.logback:logback-classic:1.4.14'
    
    // 测试
    testImplementation 'org.testng:testng:7.8.0'
    testImplementation 'org.mockito:mockito-core:5.7.0'
}

application {
    mainClass = 'com.example.myapp.Application'
}

test {
    useTestNG()
}

最佳实践

1. 包命名规范

com.{company}.{project}.{module}

示例:
com.example.myapp.user.service
com.example.myapp.order.repository

2. 类命名规范

  • ControllerUserControllerOrderController
  • ServiceUserServiceOrderService
  • RepositoryUserRepositoryOrderRepository
  • ModelUserOrder
  • DTOUserRequestUserResponse
  • EventUserCreatedEventOrderPlacedEvent
  • ListenerUserEventListenerOrderEventListener

3. 文件组织

✅ 按功能模块组织(推荐)
com.example.myapp/
├── user/
│   ├── UserController.java
│   ├── UserService.java
│   ├── UserRepository.java
│   └── User.java
└── order/
    ├── OrderController.java
    ├── OrderService.java
    ├── OrderRepository.java
    └── Order.java

✅ 按层次组织(也可以)
com.example.myapp/
├── controller/
│   ├── UserController.java
│   └── OrderController.java
├── service/
│   ├── UserService.java
│   └── OrderService.java
└── repository/
    ├── UserRepository.java
    └── OrderRepository.java

4. 配置文件组织

resources/
├── application.properties          # 通用配置
├── application-dev.properties      # 开发环境
├── application-test.properties     # 测试环境
├── application-prod.properties     # 生产环境
├── logback.xml                     # 日志配置
└── db/
    ├── schema.sql                  # 数据库表结构
    └── data.sql                    # 初始化数据

5. 测试文件组织

test/java/
├── unit/                           # 单元测试
│   ├── service/
│   └── repository/
├── integration/                    # 集成测试
│   └── api/
└── performance/                    # 性能测试

多模块项目

结构示例

my-app/
├── my-app-api/                     # API 模块
│   └── src/main/java/
│       └── com/example/myapp/api/
├── my-app-service/                 # 服务模块
│   └── src/main/java/
│       └── com/example/myapp/service/
├── my-app-repository/              # 数据访问模块
│   └── src/main/java/
│       └── com/example/myapp/repository/
├── my-app-common/                  # 公共模块
│   └── src/main/java/
│       └── com/example/myapp/common/
└── settings.gradle

settings.gradle

gradle
rootProject.name = 'my-app'

include 'my-app-api'
include 'my-app-service'
include 'my-app-repository'
include 'my-app-common'

下一步

Released under the Apache License 2.0