Avatar
2
hovanvydut Beginner
hovanvydut Beginner
Cách mà ezyfox quản lý các bean
Dạ em chào anh, em có pull source code ezyfox server và chạy thử example hello word của anh.

Em có đọc qua source code nhưng vẫn chưa hiểu hết, và có một số thắc mắc, có gì nhờ anh giúp đỡ ạ:

Em thấy trong source example của anh có ví dụ sau:

@Setter
@EzyPrototype
@EzyObjectBinding(write = false)
@EzyRequestListener(GREET)
public class GreetRequestHandler
    extends ClientRequestHandler
    implements EzyDataBinding {

    private String who;

    @EzyAutoBind
    private Greeting greeting;

    @Override
    protected void execute() throws EzyBadRequestException {
        responseFactory.newObjectResponse()
            .command(GREET)
            .param("message", greeting.greet(who))
            .session(session)
            .execute();
    }
}
Và trước kia em thắc mắc làm sao để biết command nào để biết listen handler tương ứng. Sau khi đọc thì em thấy anh quản lý các lớp này bằng cách đưa nó vào một cái singletonSetEzySimpleFactoryClass. Và lúc có request gửi lên anh dựa vào command id để lấy listener tương ứng. Tuy nhiên em "KHÔNG THẤY" đoạn anh khởi tạo và add các listener này vào singletonSetEzySimpleFactoryClass. Em chỉ thấy đoạn get này ở EzyUserRequestSingletonController:
private Map<String, EzyUserRequestHandlerProxy> extractRequestHandlersFromListener() {
            List<Object> clientRequestHandlers = getClientRequestHandlers();
            Map<String, EzyUserRequestHandlerProxy> handlers = new HashMap<>();
            for (Object handler : clientRequestHandlers) {
                Class<?> handleType = handler.getClass();
                EzyRequestListener annotation = handleType.getAnnotation(EzyRequestListener.class);
                String command = EzyRequestListenerAnnotations.getCommand(annotation);
                handlers.put(command, new EzyUserRequestHandlerProxy((EzyUserRequestHandler) handler));
                logger.debug("add command {} and request handler {}", command, handler);
            }
            return handlers;
        }
private List<Object> getClientRequestHandlers() {
            return singletonFactory.getSingletons(EzyRequestListener.class);
        }
getSingletons ở EzySimpleSingletonFactory là anh duyệt qua singletonSet để tìm instance có chưa annotation EzyRequestListener
public List getSingletons(Class... annotationClasses) {
        return this.getSingletons((o) -> {
            Class[] var2 = annotationClasses;
            int var3 = annotationClasses.length;

            for(int var4 = 0; var4 < var3; ++var4) {
                Class annotationClass = var2[var4];
                if (o.getClass().isAnnotationPresent(annotationClass)) {
                    return true;
                }
            }

            return false;
        });
    }
public List getSingletons(Predicate filter) {
        List list = new ArrayList();
        Iterator var3 = this.singletonSet.iterator();

        while(var3.hasNext()) {
            Object object = var3.next();
            if (filter.test(object)) {
                list.add(object);
            }
        }

        return list;
    }
  • Answer
Remain: 5
1 Answer
Avatar
tvd12 Beginner
tvd12 Beginner
The Best Answer
Lớp GreetRequestHandler đang được sử dụng nó là một lớp listener (observer design pattern) hoặc em có thể gọi nó là handler (command design pattern) cũng ok. Nhưng nó được tạo ra bởi prototype design pattern, em có thể bắt đầu tìm hiểu từ đây nhé.

Thì logic của nó là:

1. Lấy ra danh sách bean có `@EzyRequestListener`.
2. Lấy ra command từ `@EzyRequestListener`.
3. Đưa vào map command và bean handler.

Khi có request nào gửi đến thì nó sẽ giải nén ra để lấy command rồi lấy ra bean handler để xử lý, em có thể tham khảo tại đây.

EzyFox quản lý bean theo 2 dạng là Singleton và Prototype.

  1. Singleton chỉ được khởi tạo duy nhất 1 lần, nó phù hợp với các lớp không chứa dữ liệu. Các lớp Singleton sẽ được annotation bởi các annotation khác ngoài @EzyPrototype ví dụ @EzySingleton, @EzyEventHandler, @Service tuỳ vào ngữ cảnh.
  2. Prototype được khởi tạo mỗi lần được gọi, nó phù hợp với các lớp vừa chứa dữ liệu vừa chứa xử lý, ví dụ em thấy thằng GreetRequestHandler nó vừa chứa who là dữ liệu client gửi lên vừa có hàm handle xử lý. Các lớp prototype sẽ được annotation bởi @EzyPrototype.

Em có thể truy cập để lấy bean hoặc một danh sách bean ra theo annotation, theo class type.

Em có thể tham khảo thêm docs của ezyfox bean để biết thêm chi tiết nhé.

  • 1
  • Reply
Dạ vâng em cảm ơn anh nhiều. Em cũng tìm thấy đoạn anh scan package để map mấy class vào ở EzySimpleBeanContext rồi ạ:
private void doScanPackages(Set<String> packages) {
            if (packages.size() > 0) {
                EzyReflection reflection = EzyPackages.scanPackages(packages);
                addAllClassesByReflection(reflection);
            }
        }
Anh scan tất cả class trong packageScans
 –  hovanvydut 1693043116000
Ok em  –  tvd12 1693044304000