J2EE知識整理(二)

來源:互聯網
上載者:User

標籤:style   http   java   使用   os   strong   

  就在前不久,一個資深JAVA經理兼HR跟我說,做Java web的,一定要會Spring,不止是會用,還要深入進去,看看它的實現原理,以及是怎麼編寫的,對此我表示鴨梨很大,內部結構,原理啥都只能先放著一遍,先來看看Spring是怎麼做的。

 

IOC?DI?這是個咩啊!

  關於控制反轉或者說依賴注入到底是個什麼意思,這裡就不多加說明了,Spring in Action專業度爆脖主的距離怕有該書作者到脖主的地理位置那麼遠,還是直接來看看是怎麼做的吧

  public class DbInfoServlet extends HttpServlet{

    public void service(HttpServletRequest request,HttpServletResponse response)

      throws ServletException,java.io.IOException{

      request.setCharacterEncoding("GBK");

      DbInfo dbinfo = new DbInfo();

      String result = dbinfo.queryModelInfo();

      response.setContentType("text/html;charset=UTF-8");

      response.setHeader("Cache-Control", "no-cache");

             PrintStream out = new PrintStream(response.getOutputStream());

             out.println(result);

    }

  }

 

  這是上篇中的一個servlet應用,對於類DbInfo 的使用,通過new一個新執行個體來實現。

 

  public class ModelInfoControl implements Controller {

    private ModelInfoService modelInfoService;

 

       @Override

     public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response)

             throws ServletException,java.io.IOException{

           request.setCharacterEncoding("GBK");

      String result = modelInfoService.queryModelInfo();

      response.setContentType("text/html;charset=UTF-8");

             response.setHeader("Cache-Control", "no-cache");

           PrintStream out = new PrintStream(response.getOutputStream());

           out.println(result);

           out.flush();

             out.close();

           return null;

    }

       public void setModelInfoService(ModelInfoService modelInfoService) {

           this.modelInfoService = modelInfoService;

       }

  }

 

  雖然命名略有不同,但是不影響看出差別,這裡ModelInfoService類執行個體modelInfoService,沒有使用new關鍵字去建立,而且在下方,多出了一個他的set方法。

這是如何?的,我們呼應一下標題,在這裡,建立被調用者執行個體的工作不在由調用者完成,而是在外部實現後注入調用者,所以說,這裡控制反轉了或者說,這裡依賴注入,那麼。新的問題出現了,現在,控制反轉到誰頭上了,依賴於誰去注入?

容器

  暫時讓我們忘掉之前的MyProject,忘掉上面的對於依賴注入的說明,來看一個Spring的簡單應用:

定義兩個介面,斧子和人

  public interface Axe {

        public String chop();

  }

  public interface Person {

        public void useAxe();

  }

 

  定義斧子的實作類別

  public class StoneAxe implements Axe {

    @Override

    public String chop() {

             // TODO Auto-generated method stub

             return "石斧砍柴好慢";

    }

  }

  以及人的實作類別

  public class Chinese{

    private Axe axe;

    public void setAxe(Axe axe) {

             this.axe = axe;

          }  

          public Axe getAxe() {

            return axe;

            }

  }

  最後測試Spring

  public class SpringTest {

        public static void main(String[] args) {

      ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");

             Chinese p = ctx.getBean("chinese",Chinese.class);

             System.out.println(p.getAxe().chop());

         }

  }

  輸出:石斧砍柴好慢

 

  但是,等等,這是怎麼一回事,Chinese裡明明是個介面的axe,是怎麼變成StoneAxe的執行個體的!

  我們先關注一下chinese執行個體p的建立。

  ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");

  Chinese p = ctx.getBean("chinese",Chinese.class);

  想到什麼沒,雖然跟上面的方式不太一樣,但是顯然這裡的p也沒通過new關鍵字建立,而是通過一個叫ctx的ApplicationContext執行個體建立,而ctx,顯然藉助了資料檔案bean.xml來實現自身的執行個體化。

  我們來看一下bean.xml。

  <?xml version="1.0" encoding="UTF-8"?>

  <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

    xmlns="http://www.springframework.org/schema/beans"

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

 

      <bean id="chinese" class="sun.service.Chinese">

          <property name="axe" ref="stoneAxe"/>

      </bean>

      <bean id="stoneAxe" class="sun.service.StoneAxe"/>

  </beans>

  這裡定義了兩個bean Chinese chinese和StoneAxe stoneAxe,而chinese的參數axestoneAxe的一個實現。

  這下就好理解了,p是ctx所擷取的bean chinese,這個Chinese類的執行個體中,屬性axe為bean stoneAxe看到這裡,前面的問題也就呼之欲出了,ApplicationContext類作為了各個Spring執行個體中被調用執行個體的控制和注入者,我們將其稱呼為容器,裝納bean的容器。

Spring的Web應用,Spring MVC

  扯遠了點,還是回到項目中來,添加容器設定檔applicationContext.xml

  <?xml version="1.0" encoding="UTF-8"?>

  <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"          

    xmlns="http://www.springframework.org/schema/beans"         

    xsi:schemaLocation="http://www.springframework.org/schema/beans

    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  </beans>

  並在web.xml裡對其進行配置

  <listener>

    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

  </listener>

  <context-param>

        <param-name>contextConfigLocation</param-name>

          <param-value>classpath:applicationContext.xml</param-value>

  </context-param>

 

  定義介面ModelInfoDao和實作類別ModelInfoDaoImpl

  public interface ModelInfoDao {

        //擷取模組資訊

         String queryModelInfo();

  }

  public class ModelInfoDaoImpl implements ModelInfoDao {

        Connection conn = null

        Statement stmt = null

          ResultSet rs = null;

   

         public String queryModelInfo(){

       String result = "";

       try {

         Class.forName("oracle.jdbc.driver.OracleDriver"); 

         conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "Leon", "orcl");

         stmt = conn.createStatement();

                    rs = stmt.executeQuery("select * from t_model_info");

         while(rs.next()){

           result =rs.getString("info");

         }

       } catch (ClassNotFoundException e) {

         e.printStackTrace();

       } catch (SQLException e) {

         e.printStackTrace();

       } finally {

        try {

          if(conn != null) {

              conn.close();

              conn = null;

            }

        } catch (SQLException e) {

          e.printStackTrace(); 

                   } 

              } 

              return result;

    }

  }

  註冊ModelInfoDaoImpl 的執行個體bean modelInfoDao。

  <bean id="modelInfoDao" class="dao.ModelInfoDaoImpl"/>

 

  定義介面ModelInfoService和實作類別ModelInfoServiceImpl

  public interface ModelInfoService {

         String queryModelInfo();

   }

  public class ModelInfoServiceImpl implements ModelInfoService {

 

         private ModelInfoDao modelInfo;

     @Override

            public String queryModelInfo() {

                String result = modelInfo.queryModelInfo();

                return result;

            }

            public void setDbInfo(ModelInfoDao dbInfo) {

                  this.modelInfo = dbInfo;

            }

            public ModelInfoDao getModelInfo() {

                   return modelInfo;

            }

            public void setModelInfo(ModelInfoDao modelInfo) {

                   this.modelInfo = modelInfo;

            }

  }

 

  註冊ModelInfoServiceImpl的執行個體bean modelInfoServiceImpl,並將bean modelInfoDao作為參數modelInfo注入其中。

  <bean id="modelInfoService" class="service.ModelInfoServiceImpl">

       <property name="modelInfo" ref="modelInfoDao" />

  </bean>

 

  OK,這裡,bean的準備都已經做好,只需等候召喚了。

  話說,召喚個皮卡丘都要靠精靈球網路控制,前台請求呢

控制器

  正如其命名,DispatcherServlet類來作為前置控制器,通過攔截接受前台匹配的請求請求,將其調度到指定的控制器中。

  <servlet>

    <servlet-name>dispatcher</servlet-name>

    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

    <load-on-startup>1</load-on-startup>

  </servlet>

  <servlet-mapping>

      <servlet-name>dispatcher</servlet-name>

      <url-pattern>*.htm</url-pattern>

  </servlet-mapping>

 

  這裡還需要為其添加設定檔,用來指定請求與控制器的關係

  注意,這裡設定檔命名規則為”servlet-name” + ”-servlet.xml”,存放在WEB-INF下(可通過配置修改命名與存放路徑),如此處為dispatcher-servlet.xml:

  <?xml version="1.0" encoding="UTF-8"?>

  <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

      xmlns="http://www.springframework.org/schema/beans"

      xsi:schemaLocation="http://www.springframework.org/schema/beans

      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   

  </beans>

 

  添加控制器ModelInfoControl

    public class ModelInfoControl implements Controller {

      private ModelInfoService modelInfoService;

       

      @Override

      public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws ServletException,java.io.IOException{

        request.setCharacterEncoding("GBK");

          

        String result = modelInfoService.queryModelInfo();

               response.setContentType("text/html;charset=UTF-8");

               response.setHeader("Cache-Control", "no-cache");

               PrintStream out = new PrintStream(response.getOutputStream());

               out.println(result);

               out.flush();

               out.close();

               return null;

          }

          public void setModelInfoService(

       ModelInfoService modelInfoService) {

              this.modelInfoService = modelInfoService;

          }

     }

  並將其在dispatcher-servlet.xml中註冊,並將bean modelInfoService作為參數執行個體注入

  <bean name="/modelInfo.htm" class="control.ModelInfoControl">

    <property name="modelInfoService">

             <ref bean="modelInfoService"/>

    </property>

  </bean>

 

  修改前台頁面請求,這次我們不請求servlet了,我們走Spring這條路

 

  "./dbInfoServlet" —> "modelInfo.htm"

 

  執行項目,看到醒目的首頁兩個字,開心~

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.