Spring(一)框架学习

来源:互联网 发布:aerial mac 下载 编辑:程序博客网 时间:2024/05/17 23:42

Spring是什么

Spring是一个轻量级的控制反转(IoC)和面向切口(AOP)的容器框架,它横跨三层架构,用来创建对象和管理这些对象之间的依赖关系。

轻量级和重量级?

以启动程序需要的资源来决定。比如,EJB启动的时候,需要消耗大量的资源,内存,CPU等,所以是重量级。而Spring则不,所以是轻量级框架。

轻量级是指它的创建和销毁不需要消耗太多的资源,意味着可以在程序中经常创建和销毁session的对象;重量级意味不能随意的创建和销毁它的实例,会占用很多的资源。

IoC和DI?

IoC就是控制反转(Inversion of Control),把创建对象的控制权从应用程序转移到IoC容器中。比如我们平时要使用某个对象,直接在代码中通过new来创建;而控制反转就是不直接在代码中创建对象,而是交由IoC容器来创建对象并注入到我们的程序中。

DI是依赖注入(Dependence Injection),有人说IoC就是DI,这样说也算对,网上挺多对于IoC和DI的区别比较。我比较认同的观点是,DI和IoC是从不同的角度来描述的。

依赖注入:侧重于过程, 把对象通过setter、contruct、接口等方式注入到另一个对象中作为这个对象的一个成员变量(也可能是其他);

控制反转: 侧重于结果,说的是对象的产生不是通过直接new 的,而是通过依赖注入的方式。

OOP和AOP?

OOP是面向对象编程(Object Oriented Programming),应用了三层架构后我们的业务以纵向的方式呈现。

AOP是面向切口编程(Aspect Oriented Programming),是OOP的一个横向的服务,是对OOP的进一步补充。AOP提供了安全、事务、日志等的集中式处理,通过AOP我们可以在不修改源码的情况下扩展/增强我们的功能。

Spring中面向切面编程的实现有两种方式,一种是动态代理,一种是CGLIB,动态代理必须要提供接口,而CGLIB实现使用继承。

Spring的优缺点

优点

  • 轻量级框架,低侵入性
  • 通过IoC/DI创建对象,易于维护对象间的依赖关系;面向接口编程,降低层与层之间的耦合
  • 通过AOP对功能进行扩展,遵循开闭原则
  • IoC容器创建出来的对象默认是Singleton,不需要再进行单例模式处理

缺点

业务功能依赖于Spring特有的功能,依赖于Spring环境。

依赖注入的方式

有三种依赖注入的方式:setter注入、构造方法注入、接口注入。

1. setter注入

比如我们要注入这样一个POJO对象Teacher

public class Teacher {    // 教师姓名    private String name;    // 教师所属院系    private Department dept;    // 教师的学生姓名    private List<String> list;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Department getDept() {        return dept;    }    public void setDept(Department dept) {        this.dept = dept;    }    public List<Student> getLlst() {        return llst;    }    public void setLlst(List<Student> llst) {        this.llst = llst;    }}

我们需要在applicationContext.xml文件里进行配置bean,如下:

<!-- 配置Teacher对象 --><bean id="teacher" class="com.test.Teacher">    <property name="name" value="teacherA">    <!-- 这里引用了Department对象,ref要和其id一致 -->    <property name="dept" ref="dept">    <property name="list">        <list>            <value>studentA</value>            <value>studentB</value>            <value>studentC</value>        </list>    </property></bean><!-- 配置Department对象 --><bean id="dept" class="com.test.Department">    <property name="name" value="deptA"></bean>

2. 构造方法注入

如果我们不想对每个属性都提供一个setter/getter方法,可以通过构造方法注入,如下:

public class Teacher {    // 教师姓名    private String name;    // 教师编号    private int id;    Teacher(String name, int id){        this.name = name;    }}

在xml文件中我们需要这样配置bean:

<!-- 配置Teacher对象 --><bean id="teacher" class="com.test.Teacher">    <constructor-arg index="0" value="teacherA"/>    <constructor-arg index="1" value="123456"/></bean>

3. 接口注入

比如我们有这样一个接口TeacherService

public interface TeacherService{    public void eat();}

然后有一个实现了TeacherService接口的实现类TeacherServiceImpl

public class TeacherServiceImpl implements TeacherService{    @Override    public void eat(){        System.out.println("Teacher eats...);    }}

使用注解来实现接口注入,如下:

//在实现类前加上@Service@Servicepublic class TeacherServiceImpl implements TeacherService{    ...}

在需要注入该实现类的地方设置setter/getter

public Test{    private TeacherService teacherService;    public TeacherService getTeacherService() {        return teacherService;    }    public void setTeacherService(TeacherService teacherService) {        this.teacherService= teacherService;    }}

如果不想设置setter/getter,可以使用@Autowired注解

public Test{    @Autowired    private TeacherService teacherService;}   

如果一个接口有多个实现类,可以在每个实现类的注解里加上名字:@Service(“实现类的名字”);然后在注入实现类的地方前加上@Qualifier(“实现类的名字”)来指定注入的是哪一个实现类。

参考链接

  1. http://bbs.csdn.net/topics/380176779
  2. http://blog.csdn.net/lishuangzhe7047/article/details/20740209
原创粉丝点击