Spring(一)框架學習


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
@Service
public 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

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com