1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/FishGoddess-Tuz

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
README.md 32 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
gitlife-traslator Отправлено 24.11.2024 22:22 c058e6c

Tuz 轻量级资源容器

Внимание:

v1.0 и 0.8.0-FINAL и ниже версии не совместимы! API был немного скорректирован, были удалены лишние функции, была скорректирована архитектура классов. Пожалуйста, используйте v1.0 или более поздние версии!

  • Контейнер управления ресурсами: ресурсы загружаются в память в виде пар «ключ-значение», что упрощает их использование.

  • Прозрачный контейнер ресурсов: тот же способ использования, другой загрузчик, позволяет достичь прозрачности использования ресурсов.

  • Лёгкий контейнер внедрения зависимостей: классы реализации объектов напрямую внедряются в ссылки на объекты, что позволяет отделить бизнес-логику.

  • Контейнера перехвата методов объекта: динамический прокси используется для перехватчиков методов, что позволяет разделить бизнес-логику на основную и второстепенную.

  • Набор инструментов для операций ввода-вывода: предоставляет распространённые методы ввода-вывода, упрощая работу с вводом-выводом.

Введение (Introduce)

Tuz — это облегчённый менеджер ресурсов, который помогает управлять вашими ресурсами, такими как файлы .properties и JSON. После загрузки они доступны везде, и их использование очень просто!

Он также поддерживает прозрачную загрузку и работу с ресурсами Redis.

Вы можете легко расширить его функциональность, просто реализовав несколько интерфейсов!

Встроенные плагины внедрения зависимостей позволяют легко отделять интерфейсы от классов реализации и обеспечивают элегантное программирование!

Мы будем добавлять больше функций и плагинов для управления ресурсами в будущем!

Tuz — небольшой менеджер ресурсов. Например, вы можете загрузить некоторые файлы .properties и использовать их повсюду! Вы можете расширить его, реализовав некоторые интерфейсы! Также я подготовил такие строительные плагины, как DiPlugin. Со временем он будет становиться всё лучше и лучше!


Официальный сайт Tuz: http://www.fishgoddess.cn/tuz/

Контакты: fishgoddess@qq.com

Открытый исходный код: Apache License 2.0

Как использовать (How to use)

Если вы используете Maven-проект, то всё становится проще, вам нужно только добавить несколько строк в ваш pom.xml:

<!-- https://mvnrepository.com/artifact/cn.com.fishin/Tuz -->
<dependency>
    <groupId>cn.com.fishin</groupId>
    <artifactId>Tuz</artifactId>
    <version>1.0-FINAL</version>
</dependency>

Конечно, вы также можете использовать Gradle-проект, тогда вам нужно сделать то же самое, что и в Maven-проекте:

// https://mvnrepository.com/artifact/cn.com.fishin/Tuz
compile group: 'cn.com.fishin', name: 'Tuz', version: '1.0-FINAL'

Для других инструментов сборки или репозиториев см. информацию в Maven Central. Если вы не знаете, какой URL использовать, нажмите на значок Maven Central выше или перейдите по этой ссылке: [https://mvnrepository.com/artifact/cn.com.fishin/Tuz].

Дополнительную информацию можно найти на этом веб-сайте: [https://mvnrepository.com/artifact/cn.com.fishin/Tuz].


Или вы используете обычный Java-проект и вам нужно вручную импортировать библиотеку. Мы рекомендуем перейти на Maven-проект. Если вы не хотите переключаться, вы можете скачать JAR-файл нужной вам версии, а также документацию и исходный код с GitHub: Tuz - GitHub.

Мы предоставляем две версии JAR: одну без зависимостей, другую с полными зависимостями. Выберите одну из них для загрузки.

Или, что ещё хуже, вы используете традиционный Java-проект с добавлением JAR вручную, тогда вы должны изменить свой способ разработки или загрузить JAR с GitHub: Tuz - GitHub. Мы предоставляем две версии jar, одна маленькая, но не полная, другая полная, но не маленькая. Вы должны выбрать одну из них. ``` //Tuz.reLoad(new ClasspathPropertiesLoader("test.properties", "test"));

// 如果你不再需要这个资源文件,就调用这个方法
// 注意这里的 new ClasspathPropertiesLoader("test.properties", "test") 应该要和上面 load 的一致
//Tuz.unLoad(new ClasspathPropertiesLoader("test.properties", "test"));

}


#### 2. Простой способ внедрения зависимостей
```java
// 参考 test 文件夹下的 cn.com.fishin.demo.TuzSimpleDemo
public class TuzSimpleDemo2 {

    public static void main(String[] args) throws Throwable {

        // Традиционный способ использования интерфейса:
        //xxxService service = new xxxServiceImpl();
        // Этот способ не обеспечивает реального разделения, использование Spring и подобных фреймворков может обеспечить разделение, но требует введения большого количества фреймворк-кода
        // А с помощью Tuz можно легко добиться разделения, см. ниже:
        Tuz tuz = Tuz.instance();
        tuz.load(new ClasspathPropertiesLoader("test.properties", "test"));

        // Непосредственно получить реализацию класса, без необходимости внедрять детали реализации класса
        xxxService service1 = DiPlugin.useInstance("xxxService", "test", xxxService.class);
        service1.say("Hello, tuz!");

        // Вы можете подумать, что в предыдущем методе слишком много параметров
        // Да, вы правы, это именно так. xxxService и xxxService.class
        // Когда ключ и имя класса совпадают, значение ключа на самом деле можно опустить
        // Обратите внимание, что ключ xxxService в файле конфигурации - это xxxService
        xxxService service2 = DiPlugin.useInstance(xxxService.class);
        service2.say("Hello, tuz!");

        // Точно так же вы можете не указывать пространство имен, но это приведет к повторному поиску!
        //tuz.load(new ClasspathPropertiesLoader("test.properties"));
        //xxxService service3 = DiPlugin.useInstance("xxxService", xxxService.class);
        //service3.say("Hello, Tuz!");
    }
}

3. Простое управление ресурсами, здесь в основном используется файл JSON

public class TuzSimpleDemo3 {

    public static void main(String[] args) throws Throwable {

        // Загрузить этот файл JSON
        // После загрузки вы можете свободно использовать его в глобальном масштабе
        Tuz tuz = Tuz.instance();
        tuz.load(new ClasspathJSONLoader("test.json"));

        // Рекомендуется дать этому файлу пространство имён, если оно не указано вручную, Tuz будет использовать имя файла в качестве пространства имён
        // Tuz.load(new ClasspathJSONLoader("test.json", "test"));

        // Конечно, помимо загрузки ресурсов из пути к классам, вы также можете загружать ресурсы из файловой системы
        //Tuz.load(new FileSystemJSONLoader("E:\\JavaProject\\Tuz\\src\\test\\resources\\test.json"));

        // Поскольку по умолчанию используется кодировка символов UTF8, если ваш файл не в формате UTF8, могут возникнуть проблемы с искажением символов
        // В этом случае вам нужно самостоятельно указать кодировку символов этого файла
        //Tuz.load(новый ClasspathJSONLoader ("test.json", StandardCharsets.ISO_8859_1));

        /*
        {
            "status": 0,
            "message": "success",
            "ok": true,
            "data": {
                "title": {
                    "id": "001",
                    "name": "test",
                    "null": {}
                },
                "content": [
                    {
                        "id": "001",
                        "value": "hello 001",
                        "arr": [1, "非你莫属尽快发你说的", true]
                    },
                    {
                        "id": "002",
                        "value": "hello 002"
                    }
                ]
             }
         }
         */

        // Если вам нужно сослаться на значение в этом JSON, просто обратитесь к нему следующим образом
        // Разве это не удобно? Ха-ха-ха ^_^
        System.out.println(tuz.use("status")); // ===> 0
        System.out.println(tuz.use("message")); // ===> success
        System.out.println(tuz.use("ok")); // ===> true
        System.out.println(tuz.use("data")); // ===> {"title":{"null":{},"name":"test","id":"001"},"content":[{"arr":[1,"非你莫属尽快发你说的",true],"id":"001","value":"hello 001"},{"id":"002","value":"hello 002"}]}
        System.out.println(tuz.use("data.title")); // ===> {"null":{},"name":"test","id":"001"}
        System.out.println(tuz.use("data.title.id")); // ===> 001
        System.out.println(tuz.use("data.title.name")); // ===> test
        System.out.println(tuz.use("data.title.null")); // ===> {}
        System.out.println(tuz.use("data.content")); // ===> [{"arr":[1,"bfdjhsb",true],"id":"001","value":"hello 001"},{"id":"002","value":"hello 002"}]
        System.out.println(tuz.use("data.content[0].id")); // ===> 001
        System.out.println(tuz.use("data.content[0].value")); // ===> hello 001
        System.out.println(tuz.use("data.content[0].arr")); // ===> [1,"bfdjhsb",true]
        System.out.println(tuz.use("data.content[0].arr[0]")); // ===> 1

*Примечание: данный текст является переводом исходного текста, предоставленного в запросе.* ```
Систем.аут.принталН(туз.юзэ("дата.контент[0].арр[1]")); // ===> бфджхсб
Систем.аут.принталН(туз.юзэ("дата.контент[0].арр[2]")); // ===> тру
Систем.аут.принталН(туз.юзэ("дата.контент[1].ид")); // ===> 002
Систем.аут.принталН(туз.юзэ("дата.контент[1].вэлью")); // ===> хелоу 002

// Конечно, если у вас есть несколько JSON-файлов с одинаковыми ключами, вам нужно добавить пространство имён
// Здесь «тест» — это пространство имён, которое нужно указать при вызове tuz.load
туз.лоад(нью класспазхап джсонлоадер("тест.джсон", "тест"));
систем.аут.принталН(туз.юзэ("статус", "тест")); // ===> 0

// Конечно, если вы используете в программе строку JSON, вы также можете использовать AbstractJSONLoader для загрузки и использования
финал стринг джсонстринг = "{\"титул\":{\"нулл\":{},\"нэйм\":\"тест\",\"ид\":\"001\"},\"контент\":[{\"арр\":[1,\"фэн дзи мосу цзин куай фа чжи дэ\", тру],\"ид\":\"001\",\"вэлью\":\"хелоу 001\"},{\"ид\":\"002\",\"вэлью\":\"хелоу 002\"}]}";
туз.лоад(ньют абстракстджсонлоадер(джсонстринг) {
    @оверрид
    публик стринг нэймспейс() {
        ретюрн "програм";
    }
});

систем.аут.принталН(туз.юзэ("контент[0].арр")); // ===> [1,"фэн дзи мосу цзин куай фа чжи дэ",тру]
}
// Конфигурация пользовательских настроек

публик класс тузконфигдемо {

  публик статик воид мэйн(стрэнг арс) трис тирэз {

    // Мы сначала используем cn.com.fishin.tuz.demo.TuzSimpleDemo2 как точку входа
    // Сначала посмотрим на оригинальный пример:
    туз туз = туз.инстанс();
    туз.лоад(нью класспазхап пропертислоадер("тест.пропертис"));
    хххсервис сервис = диплэг.юз инстанс(хххсервис.класс);
    сервис.сэй("Хелоу, Туз!");

    // По умолчанию созданные объекты являются одноэлементными
    // См. cn.com.fishin.tuz.core.TuzConfig
    хххсервис сервис1 = диплэг.юз инстанс(хххсервис.класс);
    хххсервис сервис2 = диплэг.юз инстанс(хххсервис.класс);
    систем.аут.принталН(сервис1 == сервис2); // возвращает ===> тру

    // Поскольку у Tuz есть один набор по умолчанию, который содержит атрибут
    // Получение экземпляра класса по умолчанию является истинным, то есть одноэлементным
    // приватная булеан синглтон = тру;
    // Вы можете напрямую установить значение по умолчанию в Tuz, но это не рекомендуется
    туз.гет конфиг().сет синглтон(фолс);

    // Таким образом, полученный объект является многоэкземплярным
    хххсервис сервис3 = диплэг.юз инстанс(хххсервис.класс);
    хххсервис сервис4 = диплэг.юз инстанс(хххсервис.класс);
    систем.аут.принталН(сервис3 == сервис4); // возвращает ===> фолс

    // Вышеупомянутое говорит, что вы можете напрямую устанавливать значения по умолчанию в Tuz, но не рекомендуется
    // Правильный способ — создать новый объект конфигурации
    тузконфиг нью конфиг = нью тузконфиг();
    нью конфиг.сет синглтон(тру);

    // Устанавливаем конфигурацию
    туз.сэт конфиг(нью конфиг);

    // Теперь полученный объект снова является одноэлементным!
    хххсервис сервис5 = диплэг.юз инстанс(хххсервис.класс);
    хххсервис сервис6 = диплэг.юз инстанс(хххсервис.класс);
    систем.аут.принталН(сервис5 == сервис6); // возвращает ===> тру
  }
}
//@Спрингбут аппликейшн
публик класс туз спринг бут демо {

  /*
   * Этот класс просто демонстрирует использование SpringBoot, и это не единственный способ его использования
   *
   * Когда-то при использовании Spring конфигурация файла могла изменять реализацию класса без изменения кода,
   * Позже был выпущен SpringBoot, который действительно упростил множество операций с конфигурацией файлов,
   * Кроме того, для микросервисов изменение реализации класса часто означает изменение сервиса, поэтому, когда возникает необходимость изменить требования и изменить код,
   * Мы обычно можем понять и принять это, и даже если мы хотим прочитать конфигурацию из файла .properties, чтобы достичь цели не изменять код и изменять реализацию класса, это несложно, в конце концов, Spring уже очень прост в чтении файлов конфигурации,
   * Однако эти бизнес-процессы на самом деле повторяются и имеют смысл, и именно здесь Tuz проявляет себя в хорошем повторном использовании и бизнес-ценности.
   */

  // Вы можете выбрать использование статического блока для инициализации Tuz
  // Конечно, вы также можете выбрать инициализацию в методе main
  статик {
      три точка туз туз = туз.инстанс();
      туз.лоад(нью класспазхап пропертислоадер("тест.пропертис", "тест"));
  }

  публик статик воид мэин(стрэнг арс) {

      // Помимо инициализации в статическом блоке, вы также можете инициализировать здесь или даже сочетать параметры args
      // Делайте выбор в пользу разных сред для инициализации Туза
      Туз.лоад(нью класспазхап пропертислоадер("тест.пропертис", "тест"));

      // Это использование SpringBoot здесь не обсуждается
      спринг аппликейшн.ран(туз спринг бут демо.класс, арс);
  }

  // Инициализация Spring Bean
  //@Бин
  публик хххсервис гэт ххх сервис() {

      // Просто верните хххСервис
      // Таким образом, вам нужно только изменить реализацию этого класса в test.properties,
      // Не нужно менять код, не нужно писать лишний код
      ретурн диплэг.юз инстанс(ххх сервис.класс);
  }
}
``` **Использование перехватчиков для достижения развязки основного и вспомогательного бизнеса**

```java
public class ProxySimpleDemo {

    /*
        // В test пакете есть пример использования метода ProxyFactory.wrap
        // Однако не рекомендуется использовать этот метод напрямую, так как этот метод больше похож на фабричный метод, предназначенный для внутреннего использования
        SimpleClass simpleClass = new SimpleClass();

        SimpleClass simpleClass1 = (SimpleClass) ProxyFactory.wrap(simpleClass,
                new InterceptorInvocationHandler(simpleClass, new Interceptor[]{
                        new TestInterceptor(),
                        new TestInterceptor(),
                        new TestInterceptor()
                }));

        simpleClass1.test();
    */

    public static void main(String[] args) throws Throwable {

        // Аналогично, сначала загрузите файл ресурсов, чтобы получить конкретный класс реализации
        Tuz tuz = Tuz.instance();
        tuz.load(new ClasspathPropertiesLoader("test.properties", "test"));

        // Непосредственно получите класс реализации, вместо того чтобы внедрять детали класса реализации
        xxxService service = DiPlugin.useInstance(xxxService.class);

        // Выше показано простейшее использование метода внедрения зависимостей
        // Но теперь вы пришли с новым требованием, вам нужно добавить два требования к существующей системе:
        // 1. Теперь система добавила redis в качестве системы кэширования, перед вызовом метода сначала найдите в системе кэширования
        // Поиск не удался, затем поиск из базы данных и загрузка данных в систему кэширования
        // 2. Необходимо добавить функцию регистрации журнала ко всем бизнес-методам
        // Эти две точки являются второстепенными бизнес-функциями, и не рекомендуется напрямую записывать их в существующий бизнес или если вы не можете изменить существующий код
        // Вам необходимо использовать идеи аспектно-ориентированного программирования для обновления вашего бизнес-класса
        // Tuz использует перехватчики для достижения этой цели
        // Интерфейс верхнего уровня перехватчика: cn.com.fishin.tuz.interceptor.Interceptor
        // Однако не рекомендуется напрямую использовать этот перехватчик, рекомендуется использовать cn.com.fishin.tuz.interceptor.DefaultInterceptor
        // Затем выборочно перепишите определенные методы для достижения определенных бизнес-функций
        // Не рекомендуется напрямую использовать эту фабрику классов, рекомендуется использовать метод cn.com.fishin.tuz.plugin.ProxyPlugin для получения объекта прокси после
        /*
        xxxService xxxService = ProxyPlugin.useInstance(xxxService.class,
                new Interceptor[]{
                        new CacheInterceptor(),
                        new LogInterceptor()
        });
        */
        // Обратите внимание: когда этот класс может быть унаследован, используйте CGlib для реализации динамического прокси
        // Если его нельзя унаследовать, используйте JDK для динамического прокси, в это время требуется, чтобы этот класс реализовал интерфейс, и используйте интерфейс для приема
        xxxService serviceProxy = ProxyPlugin.useInstance(xxxService.class, new Interceptor[]{
                new CacheInterceptor(), // Перехватчик кэша
                new LogInterceptor(), // Перехватчик журнала
        });

        // Это сравнение
        System.out.println("====================== Использование перехватчика перед бизнесом ===================");
        service.say("Не использовал перехватчик...");
        System.out.println("====================== Использование перехватчика перед бизнесом ===================");

        System.out.println("====================== Использование перехватчика после бизнеса ===================");
        serviceProxy.say("Использовать перехватчик...");
        System.out.println("====================== Использование перехватчика после бизнеса ===================");

        // Это второе сравнение
        System.out.println("====================== Использование перехватчика перед бизнесом ===================");
        service.hung(18, 16);
        System.out.println("====================== Использование перехватчика перед бизнесом ===================");

        System.out.println("====================== Использование перехватчика после бизнеса ===================");
        serviceProxy.hung(81, 61);
        System.out.println("====================== Использование перехватчика после бизнеса ===================");

        /*
        // Результат выполнения:
        ====================== Использование перехватчика перед бизнесом ===================
        Не использовал перехватчик...
        ====================== Использование перехватчика перед бизнесом ===================
        ====================== Использование перехватчика после бизнеса ===================
        Запись журнала в норме операция => public void cn.com.fishin.tuz.demo.xxxServiceImpl.say(java.lang.String)
        Поиск данных в кэше: [Ljava.lang.Object;@29774679
        Данные не найдены в кэше!
        Использовать перехватчик...
        Загрузка данных null в кэш...
        ====================== Использование перехватчика после бизнеса ===================
        ====================== Использование перехватчика перед бизнесом ===================
        18 hung 16
        ====================== Использование перехватчика перед бизнесом ===================
        ====================== Использование перехватчика после бизнеса ===================
        Запись журнала в норме операция => public void cn.com.fishin.tuz.demo.xxxServiceImpl.hung(int,int)
        Поиск данных в кэше: [Ljava.lang.Object;@26653222
        Данные найдены в кэше!
        ====================== Использование перехватчика после бизнеса ===================
        */

        // Следует отметить, что, поскольку используется CGlib, класс, который будет проксироваться, не может быть окончательным
        // То есть он должен быть наследуемым, потому что CGlib использует ASM для создания подклассов и полиморфизма для достижения эффекта динамического прокси
        // Кроме того, является ли экземпляр, созданный динамическим прокси, одноэлементным или нет, зависит от конфигурации Tuz
        // Для получения подробной информации см. cn.com.fishin.tuz.core.TuzConfig.isSingleton
        // По умолчанию используется режим одиночного экземпляра, то есть независимо от того, сколько прокси-объектов создано, они все одинаковы
        // Если вам нужен многоэкземплярный режим, вы можете изменить конфигурацию Tuz и вызвать
}
``` **7. Redis 资源加载器**

```java
public class TuzSimpleDemo4 {
    public static void main(String[] args) throws Throwable {
        // Использование RedisLoader для загрузки ресурсов на Redis
        final String namespace = "192.168.32.131:6379";

        Tuz tuz = Tuz.instance();

        Loader redisLoader = new RedisLoader(namespace,
                new JedisRedisConnection(new Jedis("192.168.32.131", 6379)));
        tuz.load(redisLoader);

        // Теперь можно использовать ресурсы на Redis как обычные ресурсы
        tuz.appendResource(redisLoader, "key", "哈哈哈");

        System.out.println("key ===> " + tuz.use("key"));
        System.out.println("key1 ===> " + tuz.use("key1"));
        System.out.println("key2 ===> " + tuz.use("key2"));

        tuz.unLoad(redisLoader);
        System.out.println("key ===> " + tuz.use("key"));
    }

    private static Map<String, String> manyEntries() {
        Map<String, String> entries = new HashMap<>(8);
        for (int i = 0; i < 4; i++) {
            entries.put("key" + i, "value" + i);
        }
        return entries;
    }
}

8. Больше использования в разработке

Вы можете легко настроить свои собственные плагины.

Например, вы можете создать свой собственный загрузчик, просто реализовав интерфейс cn.com.fishin.tuz.core.Loader.

Для получения дополнительной информации о демонстрационных примерах использования, пожалуйста, обратитесь к модулю test в cn.com.fishin.tuz.demo. Документ и несколько примеров кода, также была скорректирована структура пакета.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/FishGoddess-Tuz.git
git@api.gitlife.ru:oschina-mirror/FishGoddess-Tuz.git
oschina-mirror
FishGoddess-Tuz
FishGoddess-Tuz
v1.0-rebuild