📄 soa-jndi.xtp
字号:
<document> <header> <product>resin</product> <resin-2.0>$resin/ref/jndi.xtp</resin-2.0> <title>JNDI Resource Configuration</title> </header> <body> <summary/><p>Applications can store factory objects and configuration variablesin a global naming tree using the JNDI API. JNDI, the Java Naming andDirectory Interface, provides a global memory tree to store and lookupconfiguration objects. JNDI will typically contain configured Factoryobjects.</p><p>JNDI lets applications cleanly separate configuration from theimplementation. The application will grab the configuredfactory object using JNDI and use the factory to find and createthe resource objects. In a typical example, the application willgrab a database DataSource to create JDBC Connections. Because theconfiguration is left to the configuration files, it's easy forthe application to change databases for different customers.</p><p>Some typical factory objects include:</p><ul><li><a href="config|db">JDBC DataSource</a></li><li>EJB Home interfaces</li><li><a href="jms|index">Java Messaging Service (JMS)</a> connection factories</li><li>JavaMail connection factories</li><li>Global configuration constants</li></ul><s1 title="web-apps and JNDI Contexts"><p>Resin organizes its resources into a tree, rooted in thesystem classloader. Each Resin context is associated with a classloader,a JNDI context, and a set of resources (databases, JMS, EJB beans, etc.)</p><p>Child contexts inherit classes and resources fromthe parent contexts. For example, a database with a JNDI name"java:comp/env/jdbc/foo" belonging to the foo.com virtual host would beshared for all web-applications in that host.</p><p>When Resin detects class or configuration changes in a context, itwill reload that context and all child contexts. This is how Resinreloads an application when a servlet changes.</p><figure src="jndi_tree.gif"/><p>Each web-app gets its own JNDI copy. So a web-app named /quercusand a web-app named /cmp could each use java:comp/env/jdbc/test for adatabase pool, but would use unique pools (probably usingdifferent databases.)</p><p>This separation keeps web-apps from stepping on each other's toesand also lets each virtual host use different databases.</p><p>The web-apps can share JNDI configuration from its host, and thehosts can share JNDI configuration from the global server. Eachweb-app copies the host JNDI tree, and each host copies the serverJNDI tree. So the web-app can't affect the host's JNDI, but it canshare the host's pools.</p><p>In Resin's configuration, the context determines where the JNDIwill be shared. If the JNDI configuration is in the <host>, it willbe shared across the entire host. If it's in the <web-app>, itwill only be used in the web-app.</p><deftable><tr><th>context</th><th>scope</th></tr><tr><td>http-server</td><td>shared across all applications</td></tr><tr><td>host</td><td>shared across the virtual host</td></tr><tr><td>web-app</td><td>specific to the servlet application (.war)</td></tr></deftable><example title="host and web-app specific configuration">...<host id='foo.com'> <database name='jdbc/foo'> <driver-class>org.gjt.mm.mysql.Driver</driver-class> <driver-url>jdbc:mysql://localhost:3306/foo</driver-url> </database> <web-app id='/quercus'> <database name='jdbc/quercus'> <driver-class>org.gjt.mm.mysql.Driver</driver-class> <driver-url>jdbc:mysql://localhost:3306/quercus</driver-url> </database> </web-app></host>...</example><p>In the previous example, the <code>java:comp/env/jdbc/foo</code> pool is sharedacross all web-apps in foo.com, but the <code>java:comp/env/jdbc/quercus</code>pool is only available in the /quercus web-app.</p><p>The previous example was meant to illustrate the concept of howJNDI objects belong to a certain context, for more realisticexamples of configuring and using databases see the <a href="doc|db|">Databases</a> topic.</p></s1><s1 title="JNDI Names"><p>JNDI names look like URLs. A typical name for adatabase pool is java:comp/env/jdbc/test. The <var>java:</var> scheme isa memory-based tree. <var>comp/env</var> is the standard location forJava configuration objects and <var>jdbc</var> is the standard locationfor database pools.</p><p>Other URL schemes are allowed as well, includingRMI (rmi://localhost:1099) and LDAP. Many applications, though willstick to the java:comp/env tree.</p><deftable><tr><th>name</th><th>meaning</th></tr><tr><td>java:comp/env</td><td>Configuration environment</td></tr><tr><td>java:comp/env/jdbc</td><td>JDBC DataSource pools</td></tr><tr><td>java:comp/env/ejb</td><td>EJB remote home interfaces</td></tr><tr><td>java:comp/env/cmp</td><td>EJB local home interfaces (non-standard)</td></tr><tr><td>java:comp/env/jms</td><td>JMS connection factories</td></tr><tr><td>java:comp/env/mail</td><td>JavaMail connection factories</td></tr><tr><td>java:comp/env/url</td><td>URL connection factories</td></tr><tr><td>java:comp/UserTransaction</td><td>UserTransaction interface</td></tr></deftable></s1><s1 title="JNDI API"><p>The vast majority of applications will only need the following simplepattern to lookup objects using JNDI. Since the JNDI objects aretypically configured in the web.xml or resin.xml, servlets willtypically look up their DataSources or EJB objects once in the init()method. By looking up the object once, the application can avoid anyJNDI overhead for normal requests.</p><example title="Looking up a DataSource">import javax.naming.InitialContext;import javax.naming.Context;...Context ic = new InitialContext();DataSource pool = (DataSource) ic.lookup("java:comp/env/jdbc/test");</example><p><var>new InitialContext()</var> returns the initial context for thecurrent web-app. As explained above, each application has its ownindependent JNDI namespace. So applications and virtual hosts willnot conflict with each other's JNDI names.</p><p>The <var>lookup(subpath)</var> call finds the object at the specifiedsubpath, like a filesystem lookup. Intermediate paths, like<var>env</var> in the example above, are Context objects. There's astrong analogy between filesystem directories and JNDI Contextobjects.</p><deftable><tr><th>call</th><th>meaning</th></tr><tr><td>new InitialContext()</td><td>A new pointer to the root context</td></tr><tr><td>context.lookup("subpath")</td><td>Finds the object or context at the named path beneath the current context</td></tr></deftable><p>Applications will generally cache the results of the JNDI lookup.Once configured, factory objects don't change so they can be saved to avoidthe JNDI lookup. For example, EJB Home and DataSource factoriesdon't change once they've been configured. A well-designed applicationwill lookup the DataSource once and cache it for the next call.Servlets, for example, will often lookup the DataSource or EJB Home in the<var>init()</var> method and save them in servlet instance variables.</p><example title="Caching a DataSource in a Servlet init()">package qa;import javax.servlet.*;import javax.naming.*;public class MyServlet extends GenericServlet { DataSource _dataSource; public void init() throws ServletException { try { Context env = new InitialContext().lookup("java:comp/env"); _dataSource = (DataSource) env.lookup("jdbc/test"); } catch (Exception e) { throw new ServletException(e); } } ...}</example></s1><s1 title="JNDI configuration"><s2 title="resource"><p>Factory configuration, including configuration fordatabase pooling. <a config-tag="resource"/> putsthe DataSource in a JNDI context and also in the ServletContext.Each web-app can configure its own database pool. Resin can alsoshare a common pool by putting the resource in the <host> or inthe <server>.</p><p>More details are in the configuration documentation for the <a config-tag="resource"/> tag.page.</p></s2><s2 title="env-entry"><p>JNDI parameter configuration. The env-entry configurationis similar to the init-param for servlets, but is accessible to anyJava class in the application without needing to pass along a context.</p><p>More details are in the configuration documentation for the <a config-tag="env-entry"/> tag.</p></s2><s2 title="jndi-link" version="Resin 1.2" type="defun"><p>Links a foreign JNDI context to the Resin JNDI context.For example, you can use <var>jndi-link</var> to link in client EJBs froma foreign EJB container.</p><p>More details are in the configuration documentation for the <a config-tag="jndi-link"/> tag.</p></s2></s1><s1 title="Known JNDI Object Factories"> <s2 title="javax.sql.DataSource"><p>Configures a non-transactional JDBC data sources. More details areavailable on the <a href="config|db">database configuration</a> page.</p></s2><s2 title="javax.sql.XADataSource"><p>Configures a transactional JDBC data sources. More details areavailable on the <a href="config|db">database configuration</a> page.</p></s2><s2 title="javax.mail.Session"><p>JavaMail sessions are configured with resource. The session iscreated with <var>Session.getInstance</var> using the propertiesdefined in the init-param.</p><example><resource name='mail/MySession'> <type>javax.mail.Session</type> <init-param mail.transport.protocol='smtp'> <init-param mail.host='localhost'> <init-param mail.user='harry'></resource></example></s2></s1><s1 title="Custom Resource Objects"><p>The resource element can configure any bean-based object.A new instance of the bean is created from the nameof the class specified with <var>type</var>. To make this work, the classmust have a public zero-arg constructor.</p><p>You code your java class to accept bean-style setters. You canthen use <a href="|config|init">Bean-style initialization</a> or<var>init-param</var> elements to configure the factory'sproperties using introspection. A 'foo' property expects asetFoo method, and a 'foo-bar' property expects a setFooBar property.</p><p>An example of a custom JNDI object that uses bean-styleinitialization is the <a href="|resource|tutorial|jndi-appconfig">jndi-appconfig</a>tutorial.</p><p>The following is a short example using <var>init-param</var>:<example title="custom.MyBean">package custom;public class MyBean { private String foo; private int bar; public void setFoo(String foo) { this.foo = foo; } public void setBar(int bar) { this.bar = bar; } ...}</example><example title="Configuration for custom.MyBean"><resource jndi-name='custom/MyBean'> <type>test.MyBean</type> <init-param foo='a string'> <init-param bar='613'></resource></example></p><p>The application uses the standard jndi API to find the resource with thejndi name <var>java:comp/env/custom/MyBean</var>. needed application objects. As long as a class follows the bean patterns (atminimum a public, zero-arg constructor, and setXXX mthods for properties), itcan be configured in <code>resource</code>.</p></s1> </body></document>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -