程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Spring注入

Spring注入

編輯:關於JAVA

IOC有幾種類型

兩種,依賴注入和依賴查找

依賴注入分幾種,是哪幾種?

構造器constructor依賴注入和setter依賴注入

Spring的依賴注入的核心是Bean工廠. Bean工廠負責管理組件和它們之間的依賴關系.Spring中,這種bean用來查閱所有容器管理的組件.

你的應用程序需要通過BeanFactory接口來使用Spring的DI容器.也就是說,你的程序必須創建實現了BeanFactory接口的類來配置它的Bean和依賴關系的消息.

在Spring容器內拼湊Bean叫做裝配。裝配Bean的時候,你是在告訴容器需要哪些Bean以及容器如何使用依賴注入將它們 藕合在一起。

我們還是來用例子講吧:

就以最常用的學生、課程、學藉、成績來說:

業務層:

StudentService     CourseService
    StudentServiceImpl   CourseServiceImpl
    StudentDao       CourseDao
    StudentDaoImpl     CourseDaoImp

在業務層有兩個業務組件:學生服務和課程服務。學生服務處理所有的和學生有關的事務,而課程服務負責和課程有關的功能。這些服務都通過接口來定義。

StudentService 接口如下:

public interface StudentService{
       public Student getStuden(String id);
       public void createStudent(Student stu);
       public java.util.Set getCompletedCourse(Student stu);
    }
CourseService接口如下:
    public interface CourseService{
       public Student getCourse(String id);
       public void createCourse(Course course);
       public java.util.Set getAllCourse();
       public void enrollStudentInCourse(Course course,Student stu) throws CourseException;
     }   
  StudentServiceImpl是StudentService的實現:
     package com.springinaction.service.training;
     public class StudentServiceImpl implements StudentService{
       private StudentDao stuDao;
         public StudentServiceImpl(StudentDao sDao){
          stuDao=sDao;
       }
       public void setStudentDao(StudentDao sDao){
          stuDao=sDao;
       }
       public Student getStudent(String id){
          return stuDao.findById(id);
       }
       public void createStudent(Student stu){
          stuDao.create(stu);
       }
       public java.util.Set getCompletedCourses(Student stu){
          return stuDao.getCompletedCourses(stu);
       }
     }

StudentServiceImpl將很多職責委托給了StudentDao。StudentDao處理與數據庫的交互來讀寫學生信息。StudentDao的實現類叫StudentDaoIpl.

在這裡有兩種方法將StudentDao引用賦給StudentServiceImpl:通過它的構造函數或通過setStudentDao()方法。

CoureseServiceImpl是CoureseService的實現:

package com.springinaction.service.training;
     import java.util.iterator;
     import java.util.Set;
     public class CourseServiceImpl implements CourseService{
       private CourseDao courseDao;
       private StudentService studentService;
       private int maxStudents;
       public CourseServiceImpl(CourseDao courDao){
           this.courseDao=courDao;
       }
       public void setStudentService(StudentService stuService){
           this.studentService=stuService;
       }
       public void setMaxStudents(int maxStudents){
           this.maxStudents=maxStudents;
       }
       public int getMaxStudents(){
           return maxStudents;
       }
       public Course getCourse(String id){
          return courseDao.findById(id);
        }
       public void createCourse(Course course){
           courseDao.create(course);
        }
       public void enrollStudentInCourse(Course course,Student stu) throws
             CourseException{
           if(course.getStudent().size()>=maxStudents){
             throws new CourseException("Course is full");
          }
           enforcePrerequisites(course,student);
           course.getStudent().add(student);
           courseDao.update(course);
        }
       private void enforcePrerequisites(Course course,Student student) throws CourseException{
           Set completed=
              studentService.getCompletedCourse(student);
           Set prereqs=course.getPrerequisites();
          for(Iternate iter=prereqs.iterator(); iter.hashNext();){
             if(!completed.contains(iter.next())){
              throws new CourseException("Prerequisites are not met.")
             }
           }
      }
     }

和StudentServiceImpl一樣,CoureseServiceImpl是通過它的構造函數接受CourseDao參數。CourseDao的實現是CourseDaoImpl。

enrollStudentInCourse()方法在把學生添加到課程中之前先要調用enforcePrerequisites()方法。如果學生不能滿足先決條件,enforcePrerequisites()方法拋出CourseException,enrollStudentInCourse將重新拋出這個異常。

注意enforcePrerequisites()方法使用了StudentService實現類來獲得一個學生的所有已完成課程。這意味著除了CourseDao,CoureseServiceImpl還要與StudentService合作一滿足先決條件這個業務需求。CoureseServiceImpl通過setStudentService()方法得到它的

StudentService,不象courseDao是通過構造函數得到。這樣做的原因是因為courseDao在CoureseServiceImpl中經常被用到,所以不應該在創建CoureseServiceImpl的時候還沒有設置CourseDao屬性。

使用XML裝配:

在Spring中,有幾種容器都支持使用XML裝配BEAN,包括:

XMLBeanFactory:一種簡單的BeanFactory,它用java.io.InputStream載入上下文定義文件。

ClassPathXmlApplicationContext:一種應用上下文,它從類路徑中載入上下文定義文件。

FileSystemXmlApplicationContext:一種應用上下文,它從文件系統中載入上下文定義文件。

XmlWebApplicationContext:一種基於Spring的Web應用系統上下文,它從Web應用系統上下文中載入上下文定義文件。

所有這些面向XML的容器都使用非常簡單的XML文件來定義BEAN。上下文定義文件的根元素是<beans></beans>.<beans>有多個<bean>子元素。每個<bean>元素定義了一個bean如何被裝配到Spring容器中。

下面就是這個例子的XML配置

<beans>
    <bean id="foo"
        class="com.springinaction.Foo"/>
  <bean id="bar"
        class="com.sprionginaction.Bar"/>
   </beans>

這是個簡單的BEAN裝配XML文件在Spring配置了兩個BEAN。

添加一個BEAN:

在Spring中對一個BEAN的最基本的配置包括Bean的ID和它的全稱類名。

在上面的學生例子中,我們往文件中添加CourseDao和StudentDao的實現類的定義

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Beans PUBLIC "-//SPRING//DTD BEAN//EN"http://www.springframework.org/dtd/spring-beans.dtd”> 
   <beans>
      <bean id="courseDao" class="com.springinaction.service.training.CourseDaoImpl"/>
      <bean id="studentDao" class="com.springinaction.service.training.StudentDaoImpl"/>
   </beans>

原型與單實例:

默認情況下,Spring中的所有bean都是單例(singletons),這意味著Spring維護bean的唯一實例,所有的依賴對象引用同一實例。對

bean工廠的getBean()方法的每一次調用都返回同一個實例

<bean id="foo" class="com.springinaction.Foo" singletons="false"/>

在這裡有個屬性singletons,把它設為false就成了原型,如為TRUE,就是單例。

請大家注意每次用bean的名字調用getBean()方法都會獲得一個這個BEAN的新實例,。如果BEAN使用的是有限資源,如數據庫和網絡連接的話這樣使用就不好了。所有盡量不要把singletons設為false。除非確實需要。

通過Set方法注入依賴

public void setMaxStudents(int maxStudents){
         this.maxStudents=maxStudents;
    }
    public int getMaxStudents(){
        return maxStudents;
   }

Bean配置

<bean id="foo"
      class="com.springinactiong.Foo">
     <property name="name">
      <value>Foo MyFoo</value>
     </property>
  </bean>

假如為了限制每門課程的注冊學生人數最多30人,

<bean id="courseService">
     <property name="maxStudents">
      <value>30< /value>
      </property>
  </bean>

引用其他 bean 我們可以使用 <property>元素來設置指向其他Bean的屬性。

<property>的子元素<ref>可以實現:

<bean id="foo"
     class="com.springinactiong.Foo">
   <property name="bar">
      <ref bean="bar">
     </property>
  </bean>
   <bean id="bar"
      class="com.springinactiong.Bar"/>
<bean id="courseService"
     class="com.springinaction.service.training.CourseDaoImpl"/>
   <property name="studentService">
      <ref bean="studentService">
     </property>
  </bean>
   <bean id="studentService"
      class="com.springinaction.service.training.studentService"/>

容器賦給courseService Bean 一個studentService實例,這樣courseServiceImpl就不用自己尋找studentService了

內部 bean:

<bean id="courseService"
     class="com.springinaction.service.training.CourseServiceImpl"/>
   <property name="studentService">
    <bean class="com.springinaction.service.training.StudentServiceImpl"/>
  </property>
  </bean>

這種裝配引用的方式的缺點是你無法在其他地方重用這個StudentServiceImpl實例,因為它是一個專門為courseService Bean建立的實例。

裝配集合:

List
<property name="barList">
<list>
  <value>bar1</value>
<ref bean="bar2">
</list>
</property>
Set
  <property name="barSet">
   <set>
    <value>bar1</value>
   </set>
</property>
Map
  <property name="barMap">
  <map>
   <entry key="key1">
    <value>bar1</value>
   </entry>
   <entry key="key2">
    <ref bean="bar2">
   </entry>
   </map>
  </property>
Properties
  <property name="barProps">
   <props>
    <prop key="key1">bar1</prop>
    <prop key="key2">bar2</prop>
  </props>
</property>

集合的裝配就完了

下面就講構造函數的注入

<bean id="foo"
   class="com.sprininaction.Foo">
<constructor-arg>
<value> 50</value>
</constructor-arg>
</bean>

有兩種方法來處理構造函數的不確定:

序號和類型

<bean id="foo"
   class="com.sprininaction.Foo">
<constructor-arg index="1">
<value> ...</value>
</constructor-arg>
  <constructor-arg index="0">
<value> ...</value>
</constructor-arg>
</bean>
<bean id="foo"
   class="com.sprininaction.Foo">
<constructor-arg type="java.lang.String">
<value>Spring</value>
</constructor-arg>
  <constructor-arg type="java.lang.int">
<value> 30</value>
</constructor-arg>
</bean>
end

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved