美文网首页
Java J2EE中的依赖查找

Java J2EE中的依赖查找

作者: 入门小站 | 来源:发表于2020-07-05 23:25 被阅读0次

    个人看法:设计依赖查找的设计模式,是为了解耦.

    • 单一类型依赖查找
      • JNDI javax.naming.Context#lookup
      • JavaBeans java.beans.beancontext.BeanContext
    • 集合类型依赖查找
      • java.beans.beancontext.BeanContext#getCurrentServiceSelectors
    • 层析性依赖查找

    Springboot中使用JNDI

    JNDI即Java Naming and Directory Interface(JAVA命名和目录接口),那么java命名目的就是为了记录一些不方便记录的内容,就像人的名字或DNS中的域名与IP的关系。

    两种模式
    1. Springboot Embedded Tomcat(嵌入Tomcat)使用JNDI
    2. Springboot WAR 使用JNDI

    1. Springboot Embedded Tomcat(嵌入Tomcat)使用JNDI

    • 启用默认禁用的JNDI命名。
    • 构建一个ContextResource对象,然后添加到Context对象中

    java:/comp/env/ 固定写法

    JndiConfig.java

    package com.rumenz;
    
    import org.apache.catalina.Context;
    import org.apache.catalina.startup.Tomcat;
    import org.apache.tomcat.util.descriptor.web.ContextResource;
    import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
    import org.springframework.boot.web.embedded.tomcat.TomcatWebServer;
    import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.jndi.JndiObjectFactoryBean;
    import org.springframework.stereotype.Component;
    import javax.naming.NamingException;
    import javax.sql.DataSource;
    @Component
    public class JndiConfig {
    
        @Bean
        public ServletWebServerFactory servletContainer() {
            TomcatServletWebServerFactory tomcatServletWebServerFactory = new TomcatServletWebServerFactory() {
                @Override
                protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
                    tomcat.enableNaming(); //启用默认禁用的JNDI命名
                    return super.getTomcatWebServer(tomcat);
    
                }
                //数据库配置信息可以配置在文件中,数据库发生变动,只需修改配置文件,而不用修改代码.
                @Override
                protected void postProcessContext(Context context) {
                    ContextResource resource = new ContextResource();
                    resource.setName("jdbcMydb");
                    resource.setType(DataSource.class.getName());
                    resource.setProperty("driverClassName", "com.mysql.jdbc.Driver");
                    resource.setProperty("url", "jdbc:mysql://127.0.0.1:3306/test");
                    resource.setProperty("username", "root");
                    resource.setProperty("password","root1234");
                    context.getNamingResources().addResource(resource);
                }
            };
            return tomcatServletWebServerFactory;
        }
        @Bean
        public DataSource jndiDataSource() throws IllegalArgumentException,
                NamingException {
            JndiObjectFactoryBean bean = new JndiObjectFactoryBean();           // create JNDI data source
            bean.setJndiName("java:/comp/env/jdbcMydb");  // jndiDataSource is name of JNDI data source
            bean.setProxyInterface(DataSource.class);
            bean.setLookupOnStartup(true);
            bean.afterPropertiesSet();
            return (DataSource) bean.getObject();
        }
    
    }
    

    MysqlTest.java

    package com.rumenz;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Component;
    
    import javax.naming.Context;
    import javax.naming.InitialContext;
    import javax.naming.NamingException;
    import javax.sql.DataSource;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    @Component
    public class MysqlTest implements ApplicationRunner {
        public static DataSource dataSource = null;
    
       static {
           Context context = null;
           try {
               context = new InitialContext();
           } catch (NamingException e) {
               e.printStackTrace();
           }
           //根据资源名称搜索
           try {
               dataSource = (DataSource)context.lookup("java:/comp/env/jdbcMydb");
           } catch (NamingException e) {
               e.printStackTrace();
           }
           System.out.println("static-----");
       }
    
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("run---------");
            Statement stmt = null;
            try {
                Connection conn = dataSource.getConnection();
                //查询
                stmt = conn.createStatement();
                String sql = "SELECT id,name FROM qq limit 1";
                ResultSet rs = stmt.executeQuery(sql);
                while(rs.next()){
                    int id  = rs.getInt("id");
                    String name = rs.getString("name");
                    System.out.print("id: " + id);
                    System.out.println(", name: " + name);
                }
                rs.close();
                stmt.close();
                conn.close();
            } catch (Exception e) {
              e.printStackTrace();
            }
        }
    }
    

    源码:https://github.com/mifunc/springboot-jndi-Embedded-Tomcat

    2.Springboot WAR 使用JNDI

    打包成war包放到tomcat,需要修改tomcat/conf/context.xml和tomcat/conf/server.xml

    tomcat/conf/context.xml

    <ResourceLink name="jdbcMydb"
                    global="jdbcMydb"
                    auth="Container"
                    type="javax.sql.DataSource" />
    

    tomcat/conf/server.xml

    <Resource name="jdbcMydb"
              global="jdbcMydb"
              auth="Container" 
              type="javax.sql.DataSource" 
              driverClassName="com.mysql.jdbc.Driver" 
              url="jdbc:mysql://localhost:3306/test"
              username="root"
              password="root1234"
              maxActive="100" 
              maxIdle="20" 
              minIdle="5" 
              maxWait="10000"/>
    

    业务代码

    JNDIController.java

    package com.rumenz.controller;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import javax.sql.DataSource;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class JNDIController {
        @Autowired
        private DataSource dataSource;
        
        @GetMapping("/test")
        public String test() {
            try {
                Connection conn = dataSource.getConnection();
                Statement stmt = conn.createStatement();
                String sql = "SELECT id,name FROM qq limit 1";
                ResultSet rs = stmt.executeQuery(sql);
                while(rs.next()){
                    int id  = rs.getInt("id");
                    String name = rs.getString("name");
                    System.out.print("id: " + id);
                    System.out.println(", name: " + name);
                }
                rs.close();
                stmt.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    }
    
    

    源码:https://github.com/mifunc/Springboot-jndi-war-Tomcat

    java.beans.beancontext.BeanContext(单一类型依赖查找/集合类型依赖查找)

    • 单一类型依赖查找
      • java.beans.beancontext.BeanContextServicesSupport#getService
    • 集合类型依赖查找
      • java.beans.beancontext.BeanContextServicesSupport#getCurrentServiceSelectors

    层析性依赖查找

    多个BeanContext相互为父子关系. 一个service的依赖有可能在多个BeanContext

    image.png

    相关文章

      网友评论

          本文标题:Java J2EE中的依赖查找

          本文链接:https://www.haomeiwen.com/subject/hktiqktx.html