Một trong những điều bí ẩn khi bạn lập trình với EzyPlatform là bạn sẽ không cần phải có hàm main(String[] args) ở trong mã nguồn chính mà plugin của của bạn vẫn có thể khởi động cùng EzyPlatform, đây là một trong những ứng dụng của đảo ngược điều khiển (IoC - Inversion of Control) và cũng là mộ trong những nguyên tắc sống còn trong lập trình mà EzyPlatform đã áp dụng.

Đảo ngược điều khiển là gì?

EzyPlatform IoC1.png

Bình thường ứng dụng của chúng ta sẽ điều khiển các thư viện để khởi tạo và kiểm soát việc sử dụng. Còn đối với IoC thì ngược lại framework sẽ chịu trách nhiệm khởi tạo mọi thứ, ứng dụng của chúng ta cũng chỉ là mô đun cung cấp các thành phần cho framework, việc khởi tạo và kiểm soát sử dụng thế nào sẽ phụ thuộc vào framework.

Đảo ngược điều khiển trong EzyPlatform

EzyPlatform được tổ chức theo kiến trúc plugin, nghĩa là nó không được phép phụ thuộc vào một theme hay plugin cụ thể nào cả. Các theme hay plugin này là do các nhà phát triển tạo ra và nó đóng vai trò như một ứng dụng.

EzyPlatform IoC plugin.png

Ở bên trong các thành phần của EzyPlatform như admin, web, socket để có các hàm main, hàm main này sẽ quét qua các gói được chỉ định trong tập tin module.properties, ví dụ đây là của theme book-store:

type=admin-plugin
version=1.0.0
package=org.youngmonkeys.bookstore
project_name=Book Store
description=Admin for Book Store
dependencies=ezyarticle,ecommerce,ezylogin,ezymail,ezypayment,ezysupport

Gói của theme này sẽ là org.youngmonkeys.bookstore. Gói này sẽ được đăng ký với EzyPlatform. Nếu bạn tò mò hàm main của admin trông thế nào thì nó sẽ chỉ đơn giản thế này thôi:

@ComponentsScan({ 
    "org.youngmonkeys.ezyplatform"
})
@PropertiesSources({
    "admin.properties",
    "config.properties",
    "settings/platform.properties",
    "settings/setup.properties"
})
public class AdminStartup {

    public static void main(String[] args) throws Exception {
        EzyHttpApplicationBootstrap.start(AdminStartup.class);
    }
}

Ở đây EzyPlatform sẽ mặc định quét qua gói org.youngmonkeys.ezyplatform và các tập tin cấu hình mặc định trước. Ở bên trong gói org.youngmonkeys.ezyplatform.admin.config sẽ có lớp AdminPackagesToScanProvider:

public class AdminPackagesToScanProvider implements EzyPackagesToScanProvider {
    
    private final AdminModulePropertiesReader modulePropertiesReader;
    private final AdminModuleMetadataInteractor moduleMetadataInteractor;
    
    private static final String FOLDER_PLUGINS = "admin/plugins";
    
    public AdminPackagesToScanProvider() {
        this.modulePropertiesReader = new AdminModulePropertiesReader();
        this.moduleMetadataInteractor = new AdminModuleMetadataInteractor(
            new ObjectMapperBuilder().build()
        );
    }
    
    @Override
    public Set<String> provide() {
        String ezyplatformHome = readConfigAndGetEzyHomePathString();
        Map<String, ModuleMetadata> moduleMetadataMap = moduleMetadataInteractor
            .readAdminPluginMetadataMap(ezyplatformHome);
        Set<String> answer = new HashSet<>();
        List<File> pluginFolders = getModuleFolders(
            ezyplatformHome,
            FOLDER_PLUGINS
        );
        for (File pluginFolder : pluginFolders) {
            ModuleMetadata moduleMetadata = moduleMetadataMap.get(
                pluginFolder.getName()
            );
            if (moduleMetadata == null) {
                continue;
            }
            if (moduleMetadata.isActive()) {
                Module moduleProperties =  modulePropertiesReader.read(
                    ModuleType.ADMIN_PLUGIN,
                    pluginFolder
                );
                answer.add(moduleProperties.getPackageName());
            }
        }
        return answer;
    }
}

Lớp này sẽ chịu trách nhiệm tìm kiếm các theme, plugin nào được kích hoạt và đưa gói vào danh sách cần được quyét.

Chính vì cơ chế quét gói tự động này nên ở mã nguồn của theme hay plugin của bạn sẽ không cần phải có một hàm main nào khác nữa. Bạn chỉ cần sử dụng các annotation được cung cấp bởi các thư viện bên trong EzyPlatform ví dụ @EzySingleton @Controller, @Service, ... là được, EzyPlatform sẽ chị trách nhiệm khởi tạo, tổ chức và sử dụng các thành phần bạn cung cấp một cách hợp lý.

Tổng kết

Với cơ chế đảo ngược phụ thuộc, EzyPlatform sẽ hỗ trợ các nhà phát triển khởi tạo và tổ chức các thành phần một cách tự động, việc còn lại của các nhà phát triển là tập trung vào cài đặt nghiệp vụ mà thôi.