【Java Web】Tomcat JNDI官网文档阅读笔记,JNDI数据源配置,JNDI自定义资源工厂配置

3 篇文章 0 订阅

Tomcat JDNI

https://tomcat.apache.org/tomcat-8.5-doc/jndi-resources-howto.html

Introduction

Tomcat为在其下运行的每个web应用程序提供了一个JNDI InitialContext(class)实现实例,其方式与Java企业版应用服务器提供的方式兼容。

Java EE标准在/WEB-INF/web.xml文件中提供了一组标准元素来引用/定义资源。

web.xml configuration

以下元素可以在web应用程序的web应用程序部署描述符(/web-inf/web.xml)中用于定义资源

  • <env-entry> - Environment entry, a single-value parameter that can be used to configure how the application will operate. (环境键值,一个单值参数,配置应用程序如何执行,感觉像是环境变量)
  • <resource-ref> - Resource reference, which is typically to an object factory for resources such as a JDBC DataSource, a JavaMail Session, or custom object factories configured into Tomcat. (资源引用,通常是个对象工厂,数据源,JavaMail或者自定义对象工厂配置
  • <resource-env-ref> - Resource environment reference, a new variation of resource-ref added in Servlet 2.4 that is simpler to configure for resources that do not require authentication information.(资源环境引用)

context.xml configuration

如果tomcat不能识别resource factory或者需要额外的配置。需要在 $CATALINA_BASE/conf/server.xml 或者每个项目的 (META-INF/context.xml) 中进行配置

Tomcat specific resource configuration is performed using the following elements in the <Context>element:

  • <Environment>: 相当于<env-entry>
  • <Resource>:相当于<resource-ref>
  • <ResourceLink>:资源链接,访问
  • <Tranaction>: 添加一个资源工厂,用于实例化UserTransaction对象实例,该实例可在java:comp/UserTransaction上使用。

如果一个资源已经在context.xml中定义,那么不需要在web.xml中进行定义。

建议在web.xml中进行定义,记录web程序的需要的资源。

  • 如果相同的配置在<Environment><env-entry> 都有定义,只有在 中的override设置为true,web.xml中的<env-entry> 才会生效

Using resources

InitialContext 在web初始化部署时配置,并且对web应用只读访问。所有资源都放在 java:comp/env 下。

// Obtain our environment naming context
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");

// Look up our data source
DataSource ds = (DataSource)
  envCtx.lookup("jdbc/EmployeeDB");

// Allocate and use a connection from the pool
Connection conn = ds.getConnection();
... use this connection to access the database ...
conn.close();

Tomcat Standard Resource Factories 标准资源工厂配置

Generic JavaBean Resources

这个资源工厂可以用来创建任何符合标准javabean命名约定的Java类的对象(例如,它有一个无参数构造函数,并且有符合setFoo()命名模式的属性设置器)。如果工厂的singleton属性设置为false,则资源工厂只会在每次对该条目进行lookup()时创建相应bean类的新实例。

  • Create Your JavaBean Class
public class MyBean {
    private String foo = "Default Foo";

    public String getFoo() {
        return (this.foo);
    }

    public void setFoo(String foo) {
        this.foo = foo;
    }

    private int bar = 0;

    public int getBar() {
        return (this.bar);
    }

    public void setBar(int bar) {
        this.bar = bar;
    }
}
  • 在 web.xml中定义
<resource-env-ref>
    <description>
        Object factory for MyBean instances.
    </description>
    <!-- JNDI获取的名称 -->
    <resource-env-ref-name>
        bean/MyBeanFactory
    </resource-env-ref-name>
    <!-- MyBean 的全路径名 -->
    <resource-env-ref-type>
        com.webapp.domain.MyBean
    </resource-env-ref-type>
</resource-env-ref>
  • 配置context.xml 的BeanFactory Resource
<?xml version="1.0" encoding="UTF-8"?>
<Context>
    <Resource name="bean/MyBeanFactory" auth="Container"
              type="com.webapp.domain.MyBean"
              factory="org.apache.naming.factory.BeanFactory"
              bar="23" foo="JNDI FOO"/>
</Context>
  • JNDI 查找
try {
    Context context = new InitialContext();
    Context env = (Context) context.lookup("java:comp/env");
    MyBean myBean = (MyBean) env.lookup("bean/MyBeanFactory");
    System.out.println(myBean); // MyBean{foo='JNDI FOO', bar=23}
} catch (NamingException e) {
    e.printStackTrace();
}

MyBean会在初始化时调用setter方法进行赋值

forceString

有些bean具有不能从字符串值自动转换为类型的属性。使用Tomcat BeanFactory设置这些属性将会失败,并出现一个NamingException。如果这些bean提供了从字符串值设置属性的方法,则可以配置Tomcat BeanFactory来使用这些方法。配置是通过forceString属性完成的。

对于String类型或原始类型或其关联的原始包装类的属性,不需要使用forceString。

  • JavaBean
public class MyBean2 {
    private InetAddress local = null;

    public InetAddress getLocal() {
        return local;
    }

    public void setLocal(InetAddress ip) {
        local = ip;
    }

    // 通过String转换为InetAddress 类型
    public void setLocal(String localHost) {
        try {
            local = InetAddress.getByName(localHost);
        } catch (UnknownHostException ex) {
        }
    }

    private InetAddress remote = null;

    public InetAddress getRemote() {
        return remote;
    }

    public void setRemote(InetAddress ip) {
        remote = ip;
    }

    public void hostName(String remoteHost) {
        try {
            remote = InetAddress.getByName(remoteHost);
        } catch (UnknownHostException ex) {
        }
    }

    @Override
    public String toString() {
        return "MyBean2{" +
                "local=" + local +
                ", remote=" + remote +
                '}';
    }
}

  • context.xml
    • 可以指定JavaBean中的方法名remote=hostName
<Context ...>
  ...
 <Resource name="bean/MyBeanFactory2" auth="Container"
              type="com.webapp.domain.MyBean2"
              factory="org.apache.naming.factory.BeanFactory"
              forceString="local,remote=hostName"
              local="localhost"
              remote="127.0.0.1"/>
  ...
</Context>
  • JNDI
try {
    Context context = new InitialContext();
    Context env = (Context) context.lookup("java:comp/env");
    MyBean myBean = (MyBean) env.lookup("bean/MyBeanFactory");
    MyBean2 myBean2 = (MyBean2) env.lookup("bean/MyBeanFactory2");
    System.out.println(myBean);
    System.out.println(myBean2); // MyBean2{local=localhost/127.0.0.1, remote=/127.0.0.1}
} catch (NamingException e) {
    e.printStackTrace();
}

JNDI配置数据源

  • MySQL依赖
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>
  • context.xml配置
<!-- 数据源配置 -->
<Resource name="jdbc/DataSource"
          auth="Container"
          type="javax.sql.DataSource"
          username="root"
          password="root"
          driverClassName="com.mysql.cj.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai"
          maxTotal="8"
          maxIdle="4"/>
  • JNDI
try {
    DataSource dataSource = (DataSource) env.lookup("jdbc/DataSource");
    Connection connection = dataSource.getConnection();
    System.out.println(connection); // jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai, UserName=root@localhost, MySQL Connector/J
} catch (Exception e) {
    e.printStackTrace();
}

Adding Custom Resource Factories 自定义资源工厂

Write A Resource Factory Class

  • 定义类实现 javax.naming.spi.ObjectFactory 接口,每次进行lookup时,会调用getObjectInstance方法

  • Object obj - ( 对于Tomcat,这将始终是一个类型对象 javax.naming.Reference )

  • Name name - 该工厂绑定到的相对于nameCtx的名称,如果没有指定名称,则为空。

  • Context nameCtx - 指定name参数的相对上下文,如果name相对于默认初始上下文,则为空。

  • Hashtable environment - 用于创建此对象的环境(可能为空)。这在Tomcat对象工厂中通常被忽略。

public class MyBeanFactory implements ObjectFactory {
    @Override
    public Object getObjectInstance(Object obj, Name name2, Context nameCtx, Hashtable<?, ?> environment) throws Exception {
        // Acquire an instance of our specified bean class
        MyBean bean = new MyBean();

        // Customize the bean properties from our attributes
        Reference ref = (Reference) obj;
        Enumeration addrs = ref.getAll();
        while (addrs.hasMoreElements()) {
            RefAddr addr = (RefAddr) addrs.nextElement();
            String name = addr.getType();
            String value = (String) addr.getContent();
            if (name.equals("foo")) {
                bean.setFoo(value);
            } else if (name.equals("bar")) {
                try {
                    bean.setBar(Integer.parseInt(value));
                } catch (NumberFormatException e) {
                    throw new NamingException("Invalid 'bar' value " + value);
                }
            }
        }

        // Return the customized instance
        return (bean);

    }
}

Declare Your Resource Requirements

<resource-env-ref>
  <description>
    Object factory for MyBean instances.
  </description>
  <resource-env-ref-name>
    bean/MyBeanFactory3
  </resource-env-ref-name>
  <resource-env-ref-type>
    com.webapp.domain.MyBean
  </resource-env-ref-type>
</resource-env-ref>

Code Your Application’s Use Of This Resource

 // 自定义资源工厂
MyBean myBean3 = (MyBean) env.lookup("bean/MyBeanFactory3");
System.out.println(myBean3);

Configure Tomcat’s Resource Factory

<!-- 自定义资源工厂 -->
<Resource name="bean/MyBeanFactory3" auth="Container"
          type="com.webapp.domain.MyBean"
          factory="com.webapp.factory.MyBeanFactory"
          singleton="false"
          bar="23"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值