簡體   English   中英

HK2依賴注入Jersey 2和Apache Shiro

[英]HK2 dependency injection with Jersey 2 and Apache Shiro

我正在使用Jersey 2.5.1創建一個rest api。 我正在使用HK2進行依賴注入。 后來我決定使用Apache Shiro進行身份驗證和授權。

在創建我自己的自定義Shiro Realm時遇到了一些問題。 在我的領域,我想注入依賴。 但是,當我運行我的應用程序時,依賴關系未得到解決。

這是我的設置:

web.xml中

<web-app 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"
    version="3.0">

<listener>
    <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>MyApplication</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>my.app.api.MyApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>MyApplication</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>ShiroFilter</filter-name>
    <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>ShiroFilter</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
    <dispatcher>ERROR</dispatcher>
</filter-mapping>

shiro.ini

[main]

authcBasicRealm = my.app.api.MyCustomRealm
matcher = my.app.api.MyCustomCredentialsMatcher
authcBasicRealm.credentialsMatcher = $matcher
cacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $cacheManager

[urls]

/** = authcBasic

MyApplication.java

public class MyApplication extends ResourceConfig {
   public MyApplication() {
      register(new ApplicationBinder());
      packages(true, "my.app.api");
   }
}

ApplicationBinder.java

public class ApplicationBinder extends AbstractBinder {
   @Override
   protected void configure() {
      bind(UserDAO.class).to(new TypeLiteral<Dao<User>>(){});
      bind(RealDatasource.class).to(DataSource.class);
   }
}

MyCustomRealm.java

public class MyCustomRealm extends JdbcRealm {

   @Inject DataSource source;

   public MyCustomRealm() {
      super();
   }

   @PostConstruct
   private void postConstruct() {
      // postConstruct is never executed
      setDataSource(source);
   }
}




所以,問題是源不是在MyCustomRealm中注入的。 Shiro不創建的所有其他類都會注入其依賴項。 可能問題是Shiro是通過ini文件創建我的CustomRealm嗎?

我在MyCustomRealm中看到的一個問題是,您希望在構建時填充DataSource。 有兩種方法可以解決這個問題; 一種是使用構造函數注入,另一種是使用post構造。 這里將使用構造函數注入:

public class MyCustomRealm extends JdbcRealm {

   private final DataSource source;

   @Inject
   public MyCustomRealm(DataSource source) {
      super();

      this.source = source;

      // source does not get injected
      setDataSource(source);
   }
}

以下是使用postConstruct執行此操作的方法:

public class MyCustomRealm extends JdbcRealm {

   @Inject DataSource source;

   public MyCustomRealm() {
      super();
   }

   @javax.annotation.PostConstruct
   private void postConstruct() {
      // source does not get injected
      setDataSource(source);
   }
}

我遇到了類似的問題,雖然這可能不再是你的問題,但我想提供我使用的解決方法。

問題是MyCustomRealm所有權。 它是由shiro在org.apache.shiro.web.env.EnvironmentLoaderListener通過讀取在Jersey servlet中hk2提供程序范圍之外的ini文件創建的。

只有在hk2的ServiceLocator提供對象時才會執行依賴注入 - shiro不了解​​此定位器,只使用其默認構造函數構造MyCustomRealm的實例。

我通過實現一個org.glassfish.jersey.server.spi.ContainerLifecycleListener解決了這個問題,它獲取了ServiceLocator和shiro的SecurityManager的句柄(通過在ServiceLocator注冊的ServletContext )。 然后它手動將數據注入shiro創建的領域。

如果您有興趣,我可以將代碼作為要點發布。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM