Spring注入

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。上下文定义文件的根元素是.有多个子元素。每个元素定义了一个bean如何被装配到Spring容器中。

下面就是这个例子的XML配置

            class="com.springinaction.Foo"/>          class="com.sprionginaction.Bar"/>  

这是个简单的BEAN装配XML文件在Spring配置了两个BEAN。

添加一个BEAN:

在Spring中对一个BEAN的最基本的配置包括Bean的ID和它的全称类名。

在上面的学生例子中,我们往文件中添加CourseDao和StudentDao的实现类的定义

                  

原型与单实例:

默认情况下,Spring中的所有bean都是单例(singletons),这意味着Spring维护bean的唯一实例,所有的依赖对象引用同一实例。对

bean工厂的getBean()方法的每一次调用都返回同一个实例

在这里有个属性singletons,把它设为false就成了原型,如为TRUE,就是单例。

请大家注意每次用bean的名字调用getBean()方法都会获得一个这个BEAN的新实例,。如果BEAN使用的是有限资源,如数据库和网络连接的话这样使用就不好了。所有尽量不要把singletons设为false。除非确实需要。

通过Set方法注入依赖

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

Bean配置

      class="com.springinactiong.Foo">           Foo MyFoo      

假如为了限制每门课程的注册学生人数最多30人,

           30       

引用其他 bean 我们可以使用 元素来设置指向其他Bean的属性。

的子元素可以实现:

     class="com.springinactiong.Foo">                         class="com.springinactiong.Bar"/>     class="com.springinaction.service.training.CourseDaoImpl"/>                         class="com.springinaction.service.training.studentService"/>

容器赋给courseService Bean 一个studentService实例,这样courseServiceImpl就不用自己寻找studentService了

内部 bean:

     class="com.springinaction.service.training.CourseServiceImpl"/>          

这种装配引用的方式的缺点是你无法在其他地方重用这个StudentServiceImpl实例,因为它是一个专门为courseService Bean建立的实例。

装配集合:

List  bar1Set         bar1   Map   

       bar1               

  Properties         bar1    bar2 

集合的装配就完了

下面就讲构造函数的注入

   class="com.sprininaction.Foo"> 50

有两种方法来处理构造函数的不确定:

序号和类型

   class="com.sprininaction.Foo"> ...  ...   class="com.sprininaction.Foo">Spring  30end

没有创造的生活不能算生活,只能算活着。

Spring注入

相关文章:

你感兴趣的文章:

标签云: