Osgi 通过API创建新的CXF总线
我正在尝试将ApacheCXF与OSGI一起使用。问题在于,我不希望使用cfg.xml文件,而是希望通过API加速我的服务端点。以下就是这样一个例子:Osgi 通过API创建新的CXF总线,osgi,cxf,Osgi,Cxf,我正在尝试将ApacheCXF与OSGI一起使用。问题在于,我不希望使用cfg.xml文件,而是希望通过API加速我的服务端点。以下就是这样一个例子: InvolvedPartySoap12EndpointImpl involvedPartyServiceImpl = new InvolvedPartySoap12EndpointImpl(); ServerFactoryBean svrFactory = new JaxWsServerFactoryBean(); svr
InvolvedPartySoap12EndpointImpl involvedPartyServiceImpl = new InvolvedPartySoap12EndpointImpl();
ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(InvolvedPartyPortType.class);
svrFactory.setAddress("/bin/InvolvedParty");
svrFactory.setBus(bus);
svrFactory.setServiceBean(involvedPartyServiceImpl);
_server = svrFactory.create();
我面临的问题是为每个OSGI捆绑包创建一个不同的CXF总线,从而允许我在每次激活/停用相应捆绑包时创建/销毁总线。复制以下Karaf命令也是一个目标:
问题是,我没有看到用于创建和销毁CXF总线的API。上面列出的卡拉夫密码在途中似乎不起作用
我认为可以在bundle中创建一个cfg.xml文件来创建总线,但是我没有看到使用给定别名获取总线的API。啊
下面的链接似乎很有希望,但在适应CXFNonSpringServlet的子类时。。。我没有相应的CXF总线,似乎也无法通过API创建:
所以我的问题是。。。有没有人通过OSGI中的API成功地获取、创建和销毁CXF总线(以及相应的servlet)
谢谢,
Randy您可以实现一个Bundle Activator,在Bundle start/stop上注册/取消注册CXF总线 要创建总线,可以使用BusFactory类。创建的总线必须注册为服务。已注册的服务保存在一个列表中,以便能够在bundle stop上注销它们 下面的例子(也许不太漂亮)应该给你一个想法:
import org.apache.cxf.Bus;
import org.apache.cxf.BusFactory;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
...
public class MyBundleActivator implements BundleActivator {
private final List<ServiceRegistration> serviceReferences = new ArrayList<>();
private Bus cxfBus;
private BundleContext bundleContext;
@Override
public void start(BundleContext bundleContext) throws Exception {
this.bundleContext = bundleContext;
createAndRegisterCxfBus();
}
private void createAndRegisterCxfBus() {
cxfBus = BusFactory.newInstance().createBus();
cxfBus.setExtension(MyBundleActivator.class.getClassLoader(), ClassLoader.class);
registerService(Bus.class.getName(), cxfBus);
}
private void registerService(String serviceTypeName, Object service) {
Dictionary properties = new Properties();
ServiceRegistration serviceReference = bundleContext.registerService(serviceTypeName, service, properties);
serviceReferences.add(serviceReference);
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
unregisterServices();
}
private void unregisterServices() {
for (ServiceRegistration serviceReference : serviceReferences) {
serviceReference.unregister();
}
}
}
有关更多信息,请参阅。CXFNonSpringServlet源代码显示此servlet子类根据需要创建CXF总线。因此,我采取的方法是简单地创建CXFNonSpringServlet类的实例,并使用所需的别名向HTTPService注册它 问题是以下代码不能在BundleActivator类中调用,因为不能保证注册servlet所需的HTTPService在bundle激活时存在。为此,我创建了一个带有HTTPService引用的组件,并在组件激活期间注册servlet。我进一步将该组件设置为“即时组件”,以确保在启动期间进行服务注册
@Component(immediate = true)
public class SoapBootstrap
{
private static final long serialVersionUID = 1L;
private static final String Alias = "/party";
private HttpService _httpService;
private CXFNonSpringServlet _servlet;
@Reference
public void setHttpService(HttpService theHttpService)
{
try {
_httpService = theHttpService;
_servlet = new CXFNonSpringServlet();
_httpService.registerServlet(Alias, _servlet, null, null);
registerEndpoints();
} catch (NamespaceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
private void registerEndpoints()
{
try {
XyzSoap12EndpointImpl xyzServiceImpl = new XyzSoap12EndpointImpl();
ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(XyzPortType.class);
svrFactory.setAddress("/xyz");
svrFactory.setBus(_servlet.getBus());
svrFactory.setServiceBean(xyzServiceImpl);
svrFactory.create();
} catch (Throwable e) {
e.printStackTrace();
} finally {
}
}
@Activate
void activate(BundleContext context)
{
}
@Deactivate
void deactivate(BundleContext context)
{
_httpService.unregister(Alias);
}
欢迎建议将此代码移动到Bundle Activator类,但请注意,有必要确保调用Bundle Activator时HTTPService可用。我实际上尝试过类似的方法,但没有成功。似乎在激活HTTPService和/或CXF捆绑包之前调用BusFactory.newInstance().createBus()会导致新总线自动与“/CXF”别名关联。当以后加载CXF捆绑包时,该代码还会创建一个新捆绑包并将其与“/CXF”别名关联。这会引起冲突。我提出了一种避免重复别名异常的方法,并将在该线程上记录该解决方案。
@Component(immediate = true)
public class SoapBootstrap
{
private static final long serialVersionUID = 1L;
private static final String Alias = "/party";
private HttpService _httpService;
private CXFNonSpringServlet _servlet;
@Reference
public void setHttpService(HttpService theHttpService)
{
try {
_httpService = theHttpService;
_servlet = new CXFNonSpringServlet();
_httpService.registerServlet(Alias, _servlet, null, null);
registerEndpoints();
} catch (NamespaceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
private void registerEndpoints()
{
try {
XyzSoap12EndpointImpl xyzServiceImpl = new XyzSoap12EndpointImpl();
ServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
svrFactory.setServiceClass(XyzPortType.class);
svrFactory.setAddress("/xyz");
svrFactory.setBus(_servlet.getBus());
svrFactory.setServiceBean(xyzServiceImpl);
svrFactory.create();
} catch (Throwable e) {
e.printStackTrace();
} finally {
}
}
@Activate
void activate(BundleContext context)
{
}
@Deactivate
void deactivate(BundleContext context)
{
_httpService.unregister(Alias);
}