亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在Spring Boot中使用嵌入式Tomcat容器創建JNDI上下文

如何在Spring Boot中使用嵌入式Tomcat容器創建JNDI上下文

白衣非少年 2019-11-12 11:17:43
import org.apache.catalina.Context;import org.apache.catalina.deploy.ContextResource;import org.apache.catalina.startup.Tomcat;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.boot.builder.SpringApplicationBuilder;import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;import org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.ImportResource;@Configuration@EnableAutoConfiguration@ComponentScan@ImportResource("classpath:applicationContext.xml")public class Application {    public static void main(String[] args) throws Exception {        new SpringApplicationBuilder()                .showBanner(false)                .sources(Application.class)                .run(args);}如果刪除@ImportResource,我的應用程序將啟動。我可以連接到tomcat實例。我可以檢查所有執行器端點。使用JConsole,我可以連接到應用程序,并且可以在MBean中看到我的數據源(Catalina->資源->上下文->“ /”-> localhost-> javax.sql.DataSource-> jdbc / mydatasource)我還通過JConsole在此處顯示了MBean(Tomcat-> DataSource-> /-> localhost-> javax.sql.DataSource-> jdbc / mydatasource)但是,當我@ImportResource時,實際上是通過JNDI查找mydatasource的,但找不到它。<bean id="myDS" class="org.springframework.jndi.JndiObjectFactoryBean">    <property name="jndiName" value="java:comp/env/jdbc/mydatasource"/></bean>我導入的xml文件的相關部分我上面配置的ContextResource具有與在將應用程序部署到tomcat容器中時要部署的context.xml中使用的參數完全相同的參數。導入到tomcat容器后,導入的Bean和應用程序可以正常工作。因此看來我現在有一個上下文,但似乎命名不正確。我嘗試了資源名稱的各種組合,但似乎無法在這種情況下生成“ comp”綁定。
查看完整描述

3 回答

?
不負相思意

TA貢獻1777條經驗 獲得超10個贊

默認情況下,JNDI在嵌入式Tomcat中處于禁用狀態,這會導致NoInitialContextException。您需要致電Tomcat.enableNaming()將其啟用。最簡單的方法是使用TomcatEmbeddedServletContainer子類:


@Bean

public TomcatEmbeddedServletContainerFactory tomcatFactory() {

    return new TomcatEmbeddedServletContainerFactory() {


        @Override

        protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(

                Tomcat tomcat) {

            tomcat.enableNaming();

            return super.getTomcatEmbeddedServletContainer(tomcat);

        }

    };

}

如果采用這種方法,則也可以DataSource通過重寫子類中的postProcessContext方法在JNDI中注冊TomcatEmbeddedServletContainerFactory。


context.getNamingResources().addResource將資源的java:comp/env背景下,因此資源的名稱應該是jdbc/mydatasource沒有java:comp/env/mydatasource。


Tomcat使用線程上下文類加載器來確定應針對哪個JNDI上下文執行查找。您將資源綁定到Web應用程序的JNDI上下文中,因此需要確保在Web應用程序的類加載器是線程上下文類加載器時執行查找。您應該可以通過將設置lookupOnStartup為來實現此false目的jndiObjectFactoryBean。您還需要設置expectedType為javax.sql.DataSource:


<bean class="org.springframework.jndi.JndiObjectFactoryBean">

    <property name="jndiName" value="java:comp/env/jdbc/mydatasource"/>

    <property name="expectedType" value="javax.sql.DataSource"/>

    <property name="lookupOnStartup" value="false"/>

</bean>

這將為DataSource創建代理,并在首次使用時而不是在應用程序上下文啟動期間執行實際的JNDI查找。


在Spring Boot示例中說明了上述方法。


查看完整回答
反對 回復 2019-11-12
?
慕容708150

TA貢獻1831條經驗 獲得超4個贊

@Bean

public TomcatEmbeddedServletContainerFactory tomcatFactory() {

? ? return new TomcatEmbeddedServletContainerFactory() {


? ? ? ? @Override

? ? ? ? protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(

? ? ? ? ? ? ? ? Tomcat tomcat) {

? ? ? ? ? ? tomcat.enableNaming();

? ? ? ? ? ? return super.getTomcatEmbeddedServletContainer(tomcat);

? ? ? ? }


? ? ? ? @Override

? ? ? ? protected void postProcessContext(Context context) {

? ? ? ? ? ? ContextResource resource = new ContextResource();

? ? ? ? ? ? resource.setName("jdbc/myDataSource");

? ? ? ? ? ? resource.setType(DataSource.class.getName());

? ? ? ? ? ? resource.setProperty("driverClassName", "your.db.Driver");

? ? ? ? ? ? resource.setProperty("url", "jdbc:yourDb");


? ? ? ? ? ? context.getNamingResources().addResource(resource);

? ? ? ? }

? ? };

}


@Bean(destroyMethod="")

public DataSource jndiDataSource() throws IllegalArgumentException, NamingException {

? ? JndiObjectFactoryBean bean = new JndiObjectFactoryBean();

? ? bean.setJndiName("java:comp/env/jdbc/myDataSource");

? ? bean.setProxyInterface(DataSource.class);

? ? bean.setLookupOnStartup(false);

? ? bean.afterPropertiesSet();

? ? return (DataSource)bean.getObject();

}


查看完整回答
反對 回復 2019-11-12
  • 3 回答
  • 0 關注
  • 1410 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號