Java 使用Spring在OSGi中创建具有范围原型的对象的不同实例
这是一个复杂的问题,所以我会尽可能清楚地解释它。我有三个Java 使用Spring在OSGi中创建具有范围原型的对象的不同实例,java,spring,jetty,osgi,apache-karaf,Java,Spring,Jetty,Osgi,Apache Karaf,这是一个复杂的问题,所以我会尽可能清楚地解释它。我有三个OSGi捆绑包A,B,C部署到apachekaraf。我还有一个安全捆绑包,由a、B、C捆绑包使用 每个A、B和C捆绑包都包含以下内容: <osgi:reference id="basicAuthHandlerFactory" interface="com.groupgti.security.handler.basicauth.BasicAuthHandlerFactory"/> <bean id="securityHa
OSGi
捆绑包A
,B
,C
部署到apachekaraf
。我还有一个安全捆绑包,由a
、B
、C
捆绑包使用
每个A
、B
和C
捆绑包都包含以下内容:
<osgi:reference id="basicAuthHandlerFactory" interface="com.groupgti.security.handler.basicauth.BasicAuthHandlerFactory"/>
<bean id="securityHandler" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="basicAuthHandlerFactory"/>
<property name="targetMethod" value="createSecurityHandler"/>
<property name="arguments">
<list>
<value type="java.lang.String">A.realm</value> <!-- The realm is depending on a bundle, A.realm, B.realm, C.realm -->
</list>
</property>
</bean>
BasicAuthFactoryHandlerImpl#createSecurityHandler(字符串域)
用于为每个捆绑包创建不同的安全处理程序实例。当Spring
MethodInvokingFactoryBean
调用createSecurityHandler
方法时,领域由bundle传递,如上述代码所示
securityHandler
Spring
bean有一个范围
原型,在这种情况下,当调用方法getBean
时,应该返回一个新创建的对象
我为安全处理程序设置的领域如下:
<bean id="securityHandler" class="org.eclipse.jetty.security.ConstraintSecurityHandler" scope="prototype">
<property name="authenticator">
<bean class="org.eclipse.jetty.security.authentication.BasicAuthenticator"/>
</property>
<property name="constraintMappings">
<list>
<ref bean="constraintMapping"/>
</list>
</property>
<property name="strict" value="false"/>
<property name="identityService" ref="identityService"/>
</bean>
<bean id="basicAuthSecurityHandler" class="com.groupgti.security.handler.basicauth.BasicAuthFactoryHandlerImpl"/>
<osgi:service ref="basicAuthSecurityHandler" interface="com.groupgti.security.handler.basicauth.BasicAuthHandlerFactory"/>
public class BasicAuthFactoryHandlerImpl implements BeanFactoryAware, BasicAuthHandlerFactory {
private static final Logger LOGGER = LoggerFactory.getLogger(BasicAuthFactoryHandlerImpl.class);
private BeanFactory factory;
@Override
public ConstraintSecurityHandler createSecurityHandler(String realm) {
ConstraintSecurityHandler handler = (ConstraintSecurityHandler) factory.getBean("securityHandler");
handler.setUserRealm(realm);
LOGGER.debug("Security handler created. Got realm: {}", realm);
return handler;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.factory = beanFactory;
}
}
创建每个包的处理程序后,一切正常。但问题是,所有bundle的领域在某种程度上都是从第一个启动的bundle传递的相同领域。我确信我在不同的bundle中的每个Spring
配置中传递了不同的领域,但是领域总是从第一个启动的bundle开始,并且它不能正常工作
有人知道问题出在哪里吗?问题是您从beanFactory获得了一个“securityHandler”。因此,只有一个共享实例。在createSecurityHandler中,您应该创建一个新对象并返回它 我能够找出为什么在应用程序之间共享同一实例的问题。我的所有捆绑包
A
、B
和C
,都使用了以下内容:
<httpj:engine-factory bus="cxf">
<httpj:engine port="8020">
<httpj:threadingParameters minThreads="5" maxThreads="15"/>
<httpj:handlers>
<ref bean="securityHandler"/>
<ref bean="ipFilteringHandler"/>
</httpj:handlers>
<httpj:sessionSupport>true</httpj:sessionSupport>
</httpj:engine>
</httpj:engine-factory>
真的
为了创建安全处理程序,Jetty使用了相同的端口
8020
。它无法在同一个端口上处理不同的处理程序。如果我将端口更改为完全不同,那么一切都正常。但这不是我的解决办法。解决方案是让一个领域供所有bundle使用。AFAIR这里的问题更多的是spring代理的方式。原因代理是针对服务引用而不是服务执行的。您可能需要正确配置它以使用正确的代理
我认为下面的内容可能会有所帮助:
ServiceReference nativeReference = ((ServiceReferenceProxy)serviceReference).getTargetServiceReference()
我试过了,没用。还是有同样的问题。安全处理程序有一个作用域原型,因此从spring文档中,它应该返回一个对象的新实例。问题不在那里。