Вы совершенно правы, чтобы быть затронутыми - вызовы статического метода особенно проблематичны для поблочного тестирования, поскольку Вы не можете легко дразнить свои зависимости. То, что я собираюсь показать Вам, - то, как позволить Spring, контейнер МОК делает грязную работу для Вас, оставляя Вас с аккуратным, тестируемым кодом. SecurityContextHolder является классом платформы и в то время как для Вашего кода в системе защиты низкого уровня может быть нормально быть связанным с ним, Вы, вероятно, хотите выставить более опрятный интерфейс своим компонентам UI (т.е. контроллеры).
cliff.meyers упомянул, что один путь вокруг этого - создает Ваш собственный "основной" тип и вводит экземпляр в потребителей. Spring < aop:scoped-прокси /> тег, представленный в 2.x объединенный с бобовым определением объема запроса и поддержкой метода фабрики, может быть билетом к самому читаемому коду.
Это могло работать как следующее:
public class MyUserDetails implements UserDetails {
// this is your custom UserDetails implementation to serve as a principal
// implement the Spring methods and add your own methods as appropriate
}
public class MyUserHolder {
public static MyUserDetails getUserDetails() {
Authentication a = SecurityContextHolder.getContext().getAuthentication();
if (a == null) {
return null;
} else {
return (MyUserDetails) a.getPrincipal();
}
}
}
public class MyUserAwareController {
MyUserDetails currentUser;
public void setCurrentUser(MyUserDetails currentUser) {
this.currentUser = currentUser;
}
// controller code
}
Ничто сложное до сих пор, правильно? На самом деле, вероятно, уже необходимо было сделать большую часть из этого. Затем, в Вашем бобе контекст определяют ограниченный по объему запросом боб для содержания принципала:
Благодаря волшебству aop:scoped-тега-proxy, статический метод getUserDetails назовут каждый раз, когда новый Запрос HTTP входит, и любые ссылки на currentUser свойство будут разрешены правильно. Теперь поблочное тестирование становится тривиальным:
protected void setUp() {
// existing init code
MyUserDetails user = new MyUserDetails();
// set up user as you wish
controller.setCurrentUser(user);
}
Hope это помогает!
Против: вся ваша база принадлежит нам
... Серьезно:
Против: вы не контролируете среду, в которой работает ваше приложение. Те же недостатки как с аутсорсингом любого компонента. Развлечение для игрушек, а не для бизнеса (пока) ИМХО.
Различные вещи, такие как API для Google проприетарные бэкенды, такие как их система баз данных и другие «блокировки» и фреймворки, которые означают, что ваш код привязан, в некоторых потеря понимания их системы может привести к проблемам с затратами позже, если вы захотите перейти с GAE. Конечно, вы можете абстрагироваться от них.
Мне нравятся GAE, AppJet и другие. Они крутые. Но всему есть свое место. Если вам нужна свобода и возможность управлять модулями вашего языка, API, версиями синтаксиса / stdlib и многим другим ... не уступайте управление поставщику услуг.
Против: недоступно в некоторых странах (Аргентина).
Доступно во всем мире, но только через группы Google для App Engine.
Плюсы:
Минусы:
Я бы сказал, что он не предназначен для серьезного бизнеса и дорог в долгосрочной перспективе.
Pro: неограниченная масштабируемость для вашего приложения и масштабируемость по запросу.
Вы вынуждены владеть линией сотового телефона, и ваша страна + оператор связи должны иметь возможность получать международные SMS-сообщения.
(Я ненавижу мобильные телефоны, и моя мама или коллеги не получат SMS)