【问题标题】:HK2 dependency injection with Jersey 2 and Apache Shiro使用 Jersey 2 和 Apache Shiro 进行 HK2 依赖注入
【发布时间】:2014-03-06 20:46:37
【问题描述】:

我正在使用 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 吗?

【问题讨论】:

    标签: java dependency-injection shiro jersey-2.0 hk2


    【解决方案1】:

    我在 MyCustomRealm 中看到的一个问题是您希望在构建时填写 DataSource。有两种方法可以解决此问题;一种是使用构造函数注入,另一种是使用后构造。这里将使用构造函数注入:

    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);
       }
    }
    

    【讨论】:

    • 嗨。感谢您花时间回答!不幸的是,它没有用。我尝试使用@PostConstruct(我已经编辑了我的帖子),但是 postConstruct() 方法从未执行过。
    【解决方案2】:

    我遇到了类似的问题,虽然这对您来说可能不再是问题,但我想提供我使用的解决方法。

    问题在于MyCustomRealm 的所有权。它是由 shiro 在 org.apache.shiro.web.env.EnvironmentLoaderListener 中通过读取位于 Jersey servlet 中 hk2 提供程序范围之外的 ini 文件创建的。

    依赖注入仅在对象由 hk2 的 ServiceLocator 提供时进行--shiro 不知道此定位器,并且仅使用其默认构造函数构造 MyCustomRealm 的实例。

    我通过实现一个org.glassfish.jersey.server.spi.ContainerLifecycleListener 来解决这个问题,该org.glassfish.jersey.server.spi.ContainerLifecycleListener 获取ServiceLocator 和shiro 的SecurityManager 的句柄(通过ServletContext 注册到ServiceLocator)。然后它手动将数据注入 shiro 创建的领域。

    如果您有兴趣,我可以将代码发布为要点。

    【讨论】:

    • 您好,感谢您的回答。正如您所说,这对我来说不再是问题,因为我不再使用该代码库。尽管如此,不错的解决方案
    • @space 我知道这是一个老问题,但如果你还有你的例子,我会对要点感兴趣吗?
    猜你喜欢
    • 1970-01-01
    • 2016-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多