Весна как поставщик JNDI? - PullRequest
       0

Весна как поставщик JNDI?

4 голосов
/ 11 декабря 2010

Я хотел бы использовать Spring в качестве JNDI-провайдера.Это означает, что я хотел бы настроить bean-компонент в моем контексте Spring, к которому можно получить доступ через JNDI.Это будет выглядеть примерно так:

<bean class="org.some.thing.here">
    <property name="beans">
        <map>
            <entry key="w/t/f">
                <bean class="some.thing.Else">
                     // rest ommitted
                </bean>
            </entry>
        </map>
    </property>
</bean>

Затем в моем приложении (скажем, в контроллере) я хочу иметь возможность получить этот компонент через:

Context ctx = new InitialContext();
some.thing.Else bar = (some.thing.Else) ctx.lookup("w/t/f");

Как можноЯ собираюсь сделать это?Я смотрел на XBean, однако проект выглядит устаревшим (не работает с Spring 3.0.XI не думаю), и документации очень мало.

Есть ли другие варианты?Я бы также рассмотрел вариант прокрутки своего собственного класса провайдера jndi, если это не так сложно сделать.

РЕДАКТИРОВАТЬ: Я должен добавить, что у меня нет возможности использовать JNDI,библиотека, которую мы должны использовать, которая требует загрузки определенных компонентов через JNDI.Я хотел бы использовать Spring в качестве поставщика.

Ответы [ 3 ]

5 голосов
/ 11 декабря 2010

Зачем вообще использовать JNDI? Просто получите Spring ApplicationContext и получите бин от этого.

Предполагая, что вы инициализировали Spring с помощью ContextLoaderListener в своем веб-приложении, вы сможете получить контекст приложения из ServletContext. Оттуда вы можете получить любой боб, который вы объявили весной.

ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);
Object bean = context.getBean(some.thing.Else.class);

Если вам нужно использовать JDNI, вы можете создать ServletContextListener, который выполняет что-то вроде следующего в contextInitialized ():

ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(servletContext);

Object bean = context.getBean(some.thing.Else.class);

Context initCtx = new InitialContext();
Context springCtx = initCtx.createSubcontext("spring");

springCtx.bind("bean", bean);

Тогда вы сможете найти бин Spring в "spring / bean" из InitialContext.

Две вещи на заметку:

  1. Слушатель контекста, вероятно, также должен вызывать initCtx.destroySubcontext ("spring") и в contextDestroy.

  2. Пространство имен java: comp / env доступно только для чтения (по крайней мере, в Tomcat), поэтому вы ничего не можете поместить туда.


Редактор вопроса: Еще пара ясностей ...

Если вы планируете ссылаться на Spring bean-компоненты с помощью ApplicationContext, то вам нужно ContextLoaderListener, определенное в вашем файле web.xml. Это должно быть определено перед вашим пользовательским классом слушателя ... вот так:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
    <listener-class>
    org.example.sandbox.MyCustomServletContextListener
  </listener-class>
</listener> 

Кроме того, вы можете получить ServletContext, который getWebApplicationContext использует от ServletContextEvent, например:

@Override
public void contextInitialized(ServletContextEvent contextEvent) {
    try {
        ApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(contextEvent.getServletContext());

        // get a bean named "myCalendar" from the application context       
        Calendar cal = (Calendar)appContext.getBean("myCalendar");

        // bind via JNDI
        Context initialContext = new InitialContext();
        Context subCtx = initialContext.createSubcontext("sample");
        subCtx.bind("calendar", cal);

    } catch (NamingException e) { // ommitted }
}
2 голосов
/ 11 декабря 2010

AngerClown прав, не беспокойтесь о JNDI, если только вам не нужно предоставить ссылки на другие модули, которые настаивают на этом.Если вы находитесь в контейнере веб-приложения, таком как Tomcat, у него будет реестр JNDI.Используйте это.Если он не находится внутри контейнера веб-приложения, то в любом случае не имеет смысла иметь JNDI, поскольку он предназначен для сред J2EE.

Если вы находитесь внутри веб-приложения, лучший способ запустить ваше приложение - иметь основной классбыть bean-компонентом Spring, который реализует интерфейсы жизненного цикла (например, InitializingBean), чтобы получить вызов, когда пришло время запустить ваше приложение.К этому моменту ваш основной класс приложения будет внедрен со всеми его зависимостями.Это исключает необходимость прямого вызова методов ApplicationContext.

Несмотря на это, если вы должны вызывать методы для ApplicationContext и запускаться Spring, вы можете реализовать BeanContextAware и получить контекст с контекстом.

1 голос
/ 19 февраля 2014

Еще один способ написать свой собственный JndiExporter

https://blog.konstantinpavlov.net/2008/12/31/how-to-export-spring-bean-to-jndi/

...