MongoDb via jndi

前端 未结 5 1084
隐瞒了意图╮
隐瞒了意图╮ 2020-12-09 23:22

Do you know if it is possible to setup mongodb instance in spring like any other db via datasource from jndi?

Thx

相关标签:
5条回答
  • 2020-12-10 00:02

    If you mean like regular RDBMS with JDBC access, then the answer is no.

    0 讨论(0)
  • 2020-12-10 00:08

    Reusing Juan Melo's custom implementation of ObjectFactory interface (CustomMongoJNDIFactory), it can be also configured using jndi-lookup tag of Spring's jee namespace and corresponding Tomcat config in context.xml file, like this:

    spring-mongodb-persistence-context.xml:

    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:mongo="http://www.springframework.org/schema/data/mongo"
           xmlns:jee="http://www.springframework.org/schema/jee"
            xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
            http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.2.xsd
            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
    
        <jee:jndi-lookup id="mongoTemplate" jndi-name="java:/comp/env/jndi/MongoDB" expected-type="org.springframework.data.mongodb.core.MongoTemplate" />
    
        <mongo:repositories base-package="com.package.repository.mongodb" />
    
    </beans>
    

    context.xml:

    <Resource name="jndi/MongoDB"
        auth="Container"
        type="org.springframework.data.mongodb.core.MongoTemplate"
        factory="com.package.mongo.CustomMongoJNDIFactory"
        username="test"
        password="test"
        host="localhost"
        port="27017"
        db="test" />
    
    0 讨论(0)
  • 2020-12-10 00:09

    There is another effort to provide a JDBC driver impl for MongoDB. Here:

    https://sourceforge.net/projects/mongojdbcdriver

    Not complete by any measure, but will hopefully provide a JDBC implementation that is familiar to Java developers soon.

    0 讨论(0)
  • 2020-12-10 00:16

    To do this, you'll need a JDBC driver impl for MongoDB. I have only found one, and it's referred as "experimental" from the MongoDB page: GitHub JDBC Driver for MongoDB .

    to workaroud this limitation, you could setup some Spring beans and create a MongoDB implementation for your application DAO (this way, you won't need to change the DAO interface and it's client components).

    This articles may help:

    • Plain Simple MongoDB Spring Integration
    • Migrating a Spring/Hibernate application to MongoDB
    0 讨论(0)
  • 2020-12-10 00:25

    Yes it is possible, why relying in someone elses code when you can create your own JNDI factory? just create a class that implements javax.naming.spi.ObjectFactory and a bean that pulls mongo from the JNDI context, I configured this for spring data-mongo MongoTemplate object.

    public class CustomMongoJNDIFactory implements ObjectFactory {
    
    public Object getObjectInstance(Object obj, Name name, Context nameCtx,
            Hashtable<?, ?> environment) throws Exception {
    
        validateProperty(obj, "Invalid JNDI object reference");
    
        MongoTemplate mongoTemplate = null;
        String db = null;
        String host = null;
        String username = null;
        String password = null;
        int port = 27017;
    
        Reference ref = (Reference) obj;
        Enumeration<RefAddr> props = ref.getAll();
        while (props.hasMoreElements()) {
            RefAddr addr = (RefAddr) props.nextElement();
            String propName = addr.getType();
            String propValue = (String) addr.getContent();
            if (propName.equals("db")) {
                db = propValue;
            } else if (propName.equals("host")) {
                host = propValue;
            } else if (propName.equals("username")) {
                username = propValue;
            } else if (propName.equals("password")) {
                password = propValue;
            } else if (name.equals("port")) {
                try {
                    port = Integer.parseInt(propValue);
                } catch (NumberFormatException e) {
                    throw new NamingException("Invalid port value " + propValue);
                }
            }
    
        }
    
        // validate properties
        validateProperty(db, "Invalid or empty mongo database name");
        validateProperty(host, "Invalid or empty mongo host");
        validateProperty(username, "Invalid or empty mongo username");
        validateProperty(password, "Invalid or empty mongo password");
    
        //create mongo template
        mongoTemplate = new MongoTemplate(new Mongo(host, port), db,
                new UserCredentials(username, password));
    
        return mongoTemplate;
    }
    
    
    /**
     * Validate internal String properties
     * 
     * @param property
     * @param errorMessage
     * @throws NamingException
     */
    private void validateProperty(String property, String errorMessage)
            throws NamingException {
        if (property == null || property.trim().equals("")) {
            throw new NamingException(errorMessage);
        }
    }
    
    /**
     * Validate internal Object properties
     * 
     * @param property
     * @param errorMessage
     * @throws NamingException
     */
    private void validateProperty(Object property, String errorMessage)
            throws NamingException {
        if (property == null) {
            throw new NamingException(errorMessage);
        }
    }
    

    }

    Spring bean:

    @Configuration
    @Qualifier("mongoTemplate")
    public class CustomMongoTemplate  {
    
    
     public @Bean MongoTemplate mongoTemplate() throws Exception {
         Context initCtx = new InitialContext();
         Context envCtx = (Context) initCtx.lookup("java:comp/env");
         return (MongoTemplate) envCtx.lookup("bean/MyMongoBean");
        }
    }
    

    Context.xml:

    <Resource name="bean/MyMongoBean" auth="Container"
            type="org.springframework.data.mongodb.core.MongoTemplate"
            factory="com.package.CustomMongoJNDIFactory"
            host="" db="" username="" password=""/>
    

    Web.xml

        <resource-env-ref>
        <description>Mongo JNDI configuration</description>
        <resource-env-ref-name>comp/env/bean/MyMongoBean</resource-env-ref-name>
        <resource-env-ref-type>org.springframework.data.mongodb.core.MongoTemplate</resource-env-ref-type>
    </resource-env-ref>
    
    0 讨论(0)
提交回复
热议问题