JAX-WS& JSR 330 (Spring) - 无法注入依赖项

发布于 2024-12-19 11:36:45 字数 4490 浏览 7 评论 0原文

我似乎无法将一个简单的 bean 注入到我的 @WebService 中。在类路径上使用 Spring 并定义了 javax.inject 依赖项后,我创建了一个简单的 JAX-WS Web 服务,其中包含一些底层接口驱动的 DAO 等:

@Named
@WebService(name = "NoteStorage", serviceName = "NoteStorageWS")
public class NoteStorageWS implements NoteStore {

    private static final Log l = LogFactory.getLog(NoteStorageWS.class);

    @Named("NoteDAO")
    @Inject
    private NoteDAO noteDAO;

    public NoteStorageWS() {
        super();
    }

    @Override
    @WebMethod
    public StorageState takeNote(String note) {
        try {
            l.info(format("Service received message: '%s'", note));

            Note n = new Note();
            n.setContent(note);
            noteDAO.store(n);

        } catch (Exception e) {
            l.error(e);
            return StorageState.FAILURE;
        }
        return StorageState.SUCCESS;
    }

    @WebMethod(exclude = true)
    public void setNoteDAO(NoteDAO noteDAO) {
        this.noteDAO = noteDAO;
    }
}

NoteDAO 刚刚实现:FlatFileNoteDAO 定义如下:

@Named("NoteDAO")
public class FlatFileNoteDAO implements NoteDAO {

    private static final Log l = LogFactory.getLog(FlatFileNoteDAO.class);

    @Override
    public void store(Note n) {
        if (n == null) {
            throw new IllegalArgumentException("Note was null");
        }

        try {
            l.info(format("Storing note '%s'", n));
            FileWriter fileWriter = new FileWriter(new File("Note"));
            fileWriter.write(format("%s\n", n.getContent()));
            fileWriter.close();
        } catch (IOException e) {
            throw new DataAccessException(e);
        }

    }

}

我的 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">
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/context.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <resource-env-ref>
        <description>Object factory for the CDI Bean Manager</description>
        <resource-env-ref-name>BeanManager</resource-env-ref-name>
        <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
    </resource-env-ref>
</web-app>

我通过将应用程序指向 target/note-ws/ 目录来将应用程序部署到 Glassfish,并通过以下方式执行简单的 takeNote 方法这?测试仪页面。

提交测试表单后,我在 noteDAO.store(n); 行收到一个 NullPointerException,大概是因为 noteDAO 未注入。

我可以确认 Spring 已在上下文初始化(Java EE 上下文)时被 glassfish 的日志调用:

[#|2011-12-04T16:57:24.970+0000|INFO|glassfish3.1.1|org.springframework.context.annotation.ClassPathBeanDefinitionScanner|_ThreadID=256;_ThreadName=Thread-2;|JSR-330 'javax.inject.Named' annotation found and supported for component scanning|#]

    [#|2011-12-04T16:57:25.653+0000|INFO|glassfish3.1.1|org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor|_ThreadID=256;_ThreadName=Thread-2;|JSR-330 'javax.inject.Inject' annotation found and supported for autowiring|#]

    [#|2011-12-04T16:57:25.757+0000|INFO|glassfish3.1.1|org.springframework.beans.factory.support.DefaultListableBeanFactory|_ThreadID=256;_ThreadName=Thread-2;|Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@9e39146: defining beans [noteStorageWS,NoteDAO,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy|#]

这表明我的 bean 已定义:noteStorageWSNoteDAO 等 -在。

有什么想法吗?

编辑 澄清一下,我使用 Spring 来提供 JSR 330——依赖注入——功能。

I cannot seem to inject a simple bean into my @WebService. With Spring on the classpath and javax.inject dependencies defined, I created a simple JAX-WS webservice with some underlying interface-driven DAOs etc:

@Named
@WebService(name = "NoteStorage", serviceName = "NoteStorageWS")
public class NoteStorageWS implements NoteStore {

    private static final Log l = LogFactory.getLog(NoteStorageWS.class);

    @Named("NoteDAO")
    @Inject
    private NoteDAO noteDAO;

    public NoteStorageWS() {
        super();
    }

    @Override
    @WebMethod
    public StorageState takeNote(String note) {
        try {
            l.info(format("Service received message: '%s'", note));

            Note n = new Note();
            n.setContent(note);
            noteDAO.store(n);

        } catch (Exception e) {
            l.error(e);
            return StorageState.FAILURE;
        }
        return StorageState.SUCCESS;
    }

    @WebMethod(exclude = true)
    public void setNoteDAO(NoteDAO noteDAO) {
        this.noteDAO = noteDAO;
    }
}

NoteDAOhas just implementation: FlatFileNoteDAO which is defined as follows:

@Named("NoteDAO")
public class FlatFileNoteDAO implements NoteDAO {

    private static final Log l = LogFactory.getLog(FlatFileNoteDAO.class);

    @Override
    public void store(Note n) {
        if (n == null) {
            throw new IllegalArgumentException("Note was null");
        }

        try {
            l.info(format("Storing note '%s'", n));
            FileWriter fileWriter = new FileWriter(new File("Note"));
            fileWriter.write(format("%s\n", n.getContent()));
            fileWriter.close();
        } catch (IOException e) {
            throw new DataAccessException(e);
        }

    }

}

My web.xml says:

<?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">
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/context.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <resource-env-ref>
        <description>Object factory for the CDI Bean Manager</description>
        <resource-env-ref-name>BeanManager</resource-env-ref-name>
        <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
    </resource-env-ref>
</web-app>

I deploy the application to Glassfish by pointing it to the target/note-ws/ directory and execute the simple takeNote method via the ?Tester page.

Upon submission of the tester form I get a NullPointerException at the line noteDAO.store(n);, presumably because noteDAO wasn't injected.

I can confirm that Spring has been invoked by the logs from glassfish on context initialisation (the Java EE context):

[#|2011-12-04T16:57:24.970+0000|INFO|glassfish3.1.1|org.springframework.context.annotation.ClassPathBeanDefinitionScanner|_ThreadID=256;_ThreadName=Thread-2;|JSR-330 'javax.inject.Named' annotation found and supported for component scanning|#]

    [#|2011-12-04T16:57:25.653+0000|INFO|glassfish3.1.1|org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor|_ThreadID=256;_ThreadName=Thread-2;|JSR-330 'javax.inject.Inject' annotation found and supported for autowiring|#]

    [#|2011-12-04T16:57:25.757+0000|INFO|glassfish3.1.1|org.springframework.beans.factory.support.DefaultListableBeanFactory|_ThreadID=256;_ThreadName=Thread-2;|Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@9e39146: defining beans [noteStorageWS,NoteDAO,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor]; root of factory hierarchy|#]

which says my beans are defined: noteStorageWS, NoteDAO and so-on.

Any ideas?

Edit
to clarify, I'm using Spring to provide JSR 330 -- dependency injection -- functionality.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

寻找我们的幸福 2024-12-26 11:36:45

我从来没有解决这个问题,所以我最终删除了 DI 功能,因为代码库很小并且依赖于手动依赖项解析 - 现在是普通的旧 new IFaceImpl();

I never got this solved, so I ended up removing the DI-features as the codebase was small and relied on manual dependency resolution - plain old new IFaceImpl(); for now.

囍孤女 2024-12-26 11:36:45

JAX-WS 和 Guice 需要通过 @GuiceManaged 注释进行特定集成。更多信息此处

JAX-WS and Guice require a specific integration via @GuiceManaged annotation. More info here.

执着的年纪 2024-12-26 11:36:45

将业务逻辑移至单独的 bean 中,并使用 @Configurable 注解,以便 Spring 可以处理 bean 的生命周期。现在在 NoteStorageWS 中使用该 bean

    @Configurable
    public class NoteStorageUtil{
       @Named("NoteDAO")
       @Inject
       private NoteDAO noteDAO;

       public StorageState takeNote(String note) {
         try {
                l.info(format("Service received message: '%s'", note));
                Note n = new Note();
                n.setContent(note);
                noteDAO.store(n);

          } catch (Exception e) {
                l.error(e);
                return StorageState.FAILURE;
          }
          return StorageState.SUCCESS;
       }
    }

    @WebService(name = "NoteStorage", serviceName = "NoteStorageWS")
    public class NoteStorageWS implements NoteStore {
        public StorageState takeNote(String note) {
            return new NoteStorageUtil().takeNote(note)
        }
    }

或者请检查您的端点配置是否正确,以便 Web 服务端点也是一个 spring 管理的 bean。
例如:-

   <bean id="hello" class="demo.spring.service.HelloWorldImpl" />
   <jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />

检查链接

Move the business logic to a separate bean and annotate it with @Configurable so that Spring can handle the lifecycle of the bean. Now use that bean in NoteStorageWS

    @Configurable
    public class NoteStorageUtil{
       @Named("NoteDAO")
       @Inject
       private NoteDAO noteDAO;

       public StorageState takeNote(String note) {
         try {
                l.info(format("Service received message: '%s'", note));
                Note n = new Note();
                n.setContent(note);
                noteDAO.store(n);

          } catch (Exception e) {
                l.error(e);
                return StorageState.FAILURE;
          }
          return StorageState.SUCCESS;
       }
    }

    @WebService(name = "NoteStorage", serviceName = "NoteStorageWS")
    public class NoteStorageWS implements NoteStore {
        public StorageState takeNote(String note) {
            return new NoteStorageUtil().takeNote(note)
        }
    }

Or please check if your end point configuration is proper, so that the web service end point is a spring-managed bean also.
Eg:-

   <bean id="hello" class="demo.spring.service.HelloWorldImpl" />
   <jaxws:endpoint id="helloWorld" implementor="#hello" address="/HelloWorld" />

check the link

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文