2013-01-17 9 views
2

Я кратко расскажу о своих целях ниже, если есть какие-то лучшие альтернативные способы достижения того, что я хочу. This question очень похож на то, что мне нужно, но не совсем точно, что мне нужно. Мой вопрос ...Возможно ли создать один динамический прокси-сервер, который может добавить функциональность в любой конкретный класс?

У меня есть интерфейс:

public interface Command<T> extends Serializable {} 

..plus реализация:

public class EchoCommand implements Command<String> { 
    private final String stringToEcho; 

    public EchoCommand(String stringToEcho) { 
     this.stringToEcho = stringToEcho; 
    } 

    public String getStringToEcho() { 
     return stringToEcho; 
    } 
} 

Если я создаю еще один интерфейс:

public interface AuthorizedCommand { 
    String getAuthorizedUser(); 
} 

..is есть способ, которым я могу реализовать интерфейс AuthorizedCommand на EchoCommand во время выполнения, не зная тип подкласса?

public <C extends Command<T>,T> C authorize(C command) { 
    // can this be done so the returned Command is also an 
    // instance of AuthorizedCommand? 
    return (C) theDecoratedCommand; 
} 

почему ... Я использовал Нетти, чтобы построить себе очень простую структуру клиент/сервер, проверка концепции, основанной на командах. Между командой, распределенной между клиентом и сервером, и обработчиком команд существует взаимно однозначное отношение. Обработчик работает только на сервере, и их очень просто реализовать. Вот интерфейс.

public interface CommandHandler<C extends Command<T>,T> { 
    public T execute(C command); 
} 

На стороне клиента все очень просто. Сохранение простых вещей в клиенте является основной причиной, по которой я решил попробовать командный API. Клиент отправляет команду и возвращает будущее. Понятно, что вызов асинхронный, плюс клиент не имеет дело с такими вещами, как упаковка звонка в SwingWorker. Зачем создавать синхронный API для асинхронных вызовов (что-либо по сети), чтобы обернуть синхронные вызовы в асинхронных вспомогательных методах? Я использую Guava для этого.

public <T> ListenableFuture<T> dispatch(Command<T> command) 

Теперь я хочу добавить аутентификацию и авторизацию. Я не хочу, чтобы мои обработчики команд знали о авторизации, но в некоторых случаях я хочу, чтобы они могли запросить что-то относительно того, к какому пользователю выполняется эта команда. В основном я хочу иметь атрибут lastModifiedBy для некоторых данных.

Я смотрю с помощью Apache Shiro, так очевидный ответ, кажется, чтобы использовать их SubjectAwareExecutor, чтобы получить информацию об авторизации в ThreadLocal, но тогда мои обработчики должны быть осведомлены о Shiro, или мне нужно абстрагировать прочь найти некоторый способ сопоставления команд с информацией об аутентификации/авторизации в Сиро.

Поскольку каждая команда уже имеет состояние и проходит через весь мой конвейер, все гораздо проще, если я могу просто украсить команды, которые были авторизованы, чтобы они реализовали интерфейс AuthorizedCommand. Затем мои обработчики команд могут использовать информацию, которая была украшена, но она полностью необязательна.

if(command instanceof AuthorizedCommand) { 
    // We can interrogate the command for the extra meta data 
    // we're interested in. 
} 

Таким образом, я могу также развивать все, что связано с аутентификации/авторизации независимо от основной бизнес-логики моего приложения. Это также (я думаю) позвольте мне связать информацию сессии с Netty Channel или ChannelGroup, что, я думаю, имеет больше смысла для инфраструктуры NIO, так? Я думаю, что Netty 4 может даже разрешить набор типизированных атрибутов на Channel, который хорошо подходит для отслеживания таких вещей, как информация о сеансе (я еще не изучал его).

Главное, что я хочу сделать, - это очень быстро создать прототип приложения. Я хотел бы начать с диспетчера клиентской стороны, который представляет собой простую карту типов команд для управления обработчиками и полностью игнорировать сетевые и защитные стороны вещей. Как только я доволен своим прототипом, я поменю в своем диспетчере на основе Netty (используя Guice), а затем, очень поздно в цикле разработки, я добавлю Сиро.

Я бы очень признателен за любые комментарии или конструктивную критику. Если то, что я объяснил, имеет смысл делать и невозможно в простой старой Java, я бы подумал о создании этой конкретной функции на другом языке JVM. Может, Скала?

+0

Вы пробовали это? У вас будет гораздо больше шансов получить какую-то помощь, если вы действительно попробуете его, а затем опубликуйте свои результаты. –

ответ

0

Вы можете попробовать сделать что-то вроде этого:

Java: Extending Class At Runtime

Во время выполнения код будет расширить класс Command, чтобы быть реализованным и реализовать интерфейс AuthorizedCommand. Это сделало бы класс экземпляром AuthorizedCommand, сохранив исходную структуру класса Command.

Для просмотра одной из тем с ключевыми словами "final" вы не сможете расширять классы.

 Смежные вопросы

  • Нет связанных вопросов^_^