Shiro Guice: Почему инстанцируется IniRealm четыре раза?

#java #guice #shiro

#java #guice #shiro

Вопрос:

Я пытаюсь реализовать простое веб-приложение Guice Shiro.

web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app
    version="3.0"
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
>

    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <listener>
        <listener-class>GuiceServletConfig</listener-class>
    </listener>

</web-app>
  

ShiroWebModule
Расширение ShiroModule, которое настраивает веб-среду, а также позволяет настраивать цепочку фильтров

 class SecurityModule extends ShiroWebModule {


    SecurityModule(ServletContext sc) {
        super(sc);
    }

    protected void configureShiroWeb() {
      try {
            bindRealm().toConstructor(IniRealm.class.getConstructor(Ini.class));
        } catch (NoSuchMethodException e) {
            addError(e);
        }

        addFilterChain("/login/**", AUTHC);
        addFilterChain("/app/**", AUTHC);
    }

    @Provides
    Ini loadShiroIni() {
        return Ini.fromResourcePath("classpath:shiro.ini");
    }
}
  

GuiceServletContextListener

 public class GuiceServletConfig extends GuiceServletContextListener {

    private ServletContext servletContext;

    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        this.servletContext = servletContextEvent.getServletContext();
        super.contextInitialized(servletContextEvent);
    }

    @Override
    protected Injector getInjector() {

        Injector injector = Guice.createInjector(
                new SecurityModule(servletContext),
                ShiroWebModule.guiceFilterModule(),
                new GuiceServletModule()
                );
        return injector;
    }

}
  

ОТЛАДКА

 22:56:38,350 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,357 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,365 DEBUG main org.apache.shiro.realm.text.IniRealm:processDefinitions:185 - Discovered the [users] section.  Processing...
22:56:38,372 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,373 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,376  WARN main org.apache.shiro.realm.text.IniRealm:onInit:139 - Users or Roles are already populated.  Configured Ini instance will be ignored.
22:56:38,377 DEBUG main org.apache.shiro.realm.text.IniRealm:onInit:145 - Instance is already populated with users or roles.  No additional user/role population will be performed.
22:56:38,395 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,396 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,397 DEBUG main org.apache.shiro.realm.text.IniRealm:processDefinitions:185 - Discovered the [users] section.  Processing...
22:56:38,400 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,401 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,403  WARN main org.apache.shiro.realm.text.IniRealm:onInit:139 - Users or Roles are already populated.  Configured Ini instance will be ignored.
22:56:38,404 DEBUG main org.apache.shiro.realm.text.IniRealm:onInit:145 - Instance is already populated with users or roles.  No additional user/role population will be performed.
22:56:38,406 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,406 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,407 DEBUG main org.apache.shiro.realm.text.IniRealm:processDefinitions:185 - Discovered the [users] section.  Processing...
22:56:38,411 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,411 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,414  WARN main org.apache.shiro.realm.text.IniRealm:onInit:139 - Users or Roles are already populated.  Configured Ini instance will be ignored.
22:56:38,414 DEBUG main org.apache.shiro.realm.text.IniRealm:onInit:145 - Instance is already populated with users or roles.  No additional user/role population will be performed.
22:56:38,415 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,415 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,416 DEBUG main org.apache.shiro.realm.text.IniRealm:processDefinitions:185 - Discovered the [users] section.  Processing...
22:56:38,420 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
22:56:38,421 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
22:56:38,426  WARN main org.apache.shiro.realm.text.IniRealm:onInit:139 - Users or Roles are already populated.  Configured Ini instance will be ignored.
22:56:38,426 DEBUG main org.apache.shiro.realm.text.IniRealm:onInit:145 - Instance is already populated with users or roles.  No additional user/role population will be performed.
  

Почему экземпляр IniRealm создается четыре раза? Это нормально?

Спасибо.

Комментарии:

1. Подготавливает ли контейнер пул сервлетов по соображениям производительности?

2. Я использую jetty-maven-plugin

3. Вы создаете инжектор каждый раз, когда он запрашивается. Попробуйте сделать его синглтоном.

Ответ №1:

Проблема в методе bindRealm().toConstructor(конструктор-конструктор). Я использовал альтернативный способ создания экземпляра IniRealm:

 class SecurityModule extends ShiroWebModule {

  private final Logger logger = LoggerFactory.getLogger(getClass());

  SecurityModule(ServletContext sc) {
    super(sc);
  }

  @Override
  protected void configureShiroWeb() {

    bindRealm().to(IniRealm.class);
    logger.info("SecurityModule.configureShiroWeb() method called");
  }

  @Provides
  @Singleton
  IniRealm loadIniRealm(Ini ini) {

    IniRealm realm = new IniRealm(ini);
    return realm;
  }

  @Provides
  @Singleton
  Ini loadShiroIni() {

    logger.info("SecurityModule.loadShiroIni() method called");
    return Ini.fromResourcePath("classpath:shiro.ini");
  }

}
  

ОТЛАДКА:

 08:28:03,354  INFO main org.shirotest.app.SecurityModule:loadShiroIni:50 - SecurityModule.loadShiroIni() method called
08:28:03,354 DEBUG main org.apache.shiro.io.ResourceUtils:loadFromClassPath:159 - Opening resource from class path [shiro.ini]
08:28:03,370 DEBUG main org.apache.shiro.config.Ini:load:342 - Parsing [users]
08:28:03,385 DEBUG main org.apache.shiro.realm.text.IniRealm:processDefinitions:185 - Discovered the [users] section.  Processing...
  

Полный пример кода можно найти здесь: https://issues.apache.org/jira/browse/SHIRO-320