Spring是一個輕量級的企業級開源框架,Spring框架的核心是一個Ioc容器。Ioc (Inversion of Control)又稱"控制反轉",是面向對象編程中的一種設計原則,用來降低程序代碼之間的耦合度。
實戰演練:使用Spring Ioc實現業務層和數據訪問層解耦合。
1.定義數據訪問層接口:UserDao
1 2 3 4 5 6 7 8 9 10package
com.jbit.fsd.dao;
import
java.util.List;
import
com.jbit.fsd.entity.User;
public
interface
UserDao {
public
List<User> getAll();
}
2.定義了業務訪問層接口:UserService
1 2 3 4 5 6 7 8 9 10package
com.jbit.fsd.service;
import
java.util.List;
import
com.jbit.fsd.entity.User;
public
interface
UserService {
public
List<User> getAll();
}
3.定義了數據訪問層接口實習類:UserDaoImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21package
com.jbit.fsd.dao.impl;
import
java.util.ArrayList;
import
java.util.List;
import
com.jbit.fsd.dao.UserDao;
import
com.jbit.fsd.entity.User;
public
class
UserDaoImpl
implements
UserDao {
@Override
public
List<User> getAll() {
//操作數據庫讀到所有數據
List<User> list=
new
ArrayList<User>();
list.add(
new
User());
list.add(
new
User());
list.add(
new
User());
return
list;
}
}
4.定義數據訪問層接口實現類:UserServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22package
com.jbit.fsd.service.impl;
import
java.util.List;
import
com.jbit.fsd.dao.UserDao;
import
com.jbit.fsd.entity.User;
import
com.jbit.fsd.service.UserService;
public
class
UserServiceImpl
implements
UserService{
private
UserDao dao;
//通過spring注入進來
public
void
setDao(UserDao dao) {
this
.dao = dao;
}
@Override
public
List<User> getAll() {
// TODO Auto-generated method stub
return
dao.getAll();
}
}
5.在spring配置文件中配置Bean並注入業務實現類UserServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http:
//www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http:
//www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 以面向接口思想編程實現解耦和 -->
<bean id=
"userDao"
class
=
"com.jbit.fsd.dao.impl.UserDaoImpl"
>
</bean>
<bean id=
"userServiceImpl"
class
=
"com.jbit.fsd.service.impl.UserServiceImpl"
>
<!-- 需要注意是是這裡調用setDao()方法 -->
<property name=
"dao"
ref=
"userDao"
></property> <!-- 屬性注入 -->
</bean>
</beans>
6.測試類入口:
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28package
com.jbit.fsd.test;
import
java.util.List;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
import
com.jbit.fsd.dao.UserDao;
import
com.jbit.fsd.entity.User;
import
com.jbit.fsd.service.UserService;
public
class
Test {
/**
*
* Description:
* @param
* @author xiazhongwei
* @data 2016:下午12:18:37
* @return
*/
public
static
void
main(String[] args) {
ApplicationContext ac=
new
ClassPathXmlApplicationContext(
"applicationContext.xml"
);
UserService service=(UserService) ac.getBean(
"userServiceImpl"
);
List<User> list=service.getAll();
System.out.println(list.size()+
"********************"
);
}
}
上面的小例子需要Spring核心jar的支持:可到官網下載
說明:
1.Spring為dao屬性賦值是通過setDao()方法實現的,而非直接為dao屬性賦值,若屬性為dao,但是setter方法為setUserDao,Spring配置文件應該寫成name="userDao",而非name="dao";
2.除了使用ApplicationContext及其實現類,還可以通過BeanFactory接口實現類對Bean組件實施管理,ApplicationContext建立在BeanFactory的基礎之上,可以對企業級開發提供更全名的支持。
使用上面的方法通過spring的setter訪問器實現對屬性的賦值,這種方法稱設置注入,除此之外,spring還提供了通過構造方法賦值,這種稱構造注入。
定義業務實現類UserServiceImplByConstructor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23package
com.jbit.fsd.service.impl;
import
java.util.List;
import
com.jbit.fsd.dao.UserDao;
import
com.jbit.fsd.entity.User;
import
com.jbit.fsd.service.UserService;
public
class
UserServiceImplByConstructor
implements
UserService {
private
UserDao dao;
// 定義有參的構造方法JVM不會自定義無參的構造方法,需要手動加入
public
UserServiceImplByConstructor(){
}
// 用於為dao屬性賦值的構造方法
public
UserServiceImplByConstructor(UserDao dao){
this
.dao = dao;
}
@Override
public
List<User> getAll() {
return
dao.getAll();
}
}
spring配置文件中的配置:
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<!--
- Application context definition
for
JPetStore's business layer.
- Contains bean references to the transaction manager and to the DAOs in
- dataAccessContext-local/jta.xml (see web.xml's
"contextConfigLocation"
).
-->
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http:
//www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http:
//www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 以面向接口思想編程實現解耦和 -->
<bean id=
"userDao"
class
=
"com.jbit.fsd.dao.impl.UserDaoImpl"
>
</bean>
<bean id=
"userServiceImplByConstructor"
class
=
"com.jbit.fsd.service.impl.UserServiceImplByConstructor"
>
<!-- 通過定義的單參數構造為業務層的dao屬性賦值 -->
<constructor-arg>
<!-- 引用id為userDao的對象為dao屬性賦值 -->
<ref bean=
"userDao"
/>
</constructor-arg>
</bean>
</beans>
說明:一個<constructor-arg>元素表示一個構造參數,且使用時不區分順序,當構造方法的參數出現混淆,無法區分時,可以通過<constructor-arg>元素的index屬性來指定該參數的位置索引,位置從0開始,<constructor-arg>元素還提供了type屬性用來指定參數的類型,避免字符串和基本類型的混淆。
<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<!--
- Application context definition
for
JPetStore's business layer.
- Contains bean references to the transaction manager and to the DAOs in
- dataAccessContext-local/jta.xml (see web.xml's
"contextConfigLocation"
).
-->
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http:
//www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http:
//www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 以面向接口思想編程實現解耦和 -->
<bean id=
"userDao"
class
=
"com.jbit.fsd.dao.impl.UserDaoImpl"
>
</bean>
<bean id=
"userServiceImpl"
class
=
"com.jbit.fsd.service.impl.UserServiceImpl"
>
<!-- 需要注意是是這裡調用setDao()方法 -->
<span style=
"color: rgb(255, 0, 0);"
><property name=
"dao"
ref=
"userDao"
></property> </span> <!-- 屬性注入 -->
</bean>
<bean id=
"userServiceImpl"
class
=
"com.jbit.fsd.service.impl.UserServiceImpl"
>
<property name=
"username"
>
</property>
<!-- 注入直接量 -->
<value>張三</value>
</bean>
<bean id=
"userServiceImpl"
class
=
"com.jbit.fsd.service.impl.UserServiceImpl"
>
<!-- 需要注意是是這裡調用setDao()方法 -->
<span style=
"color: rgb(255, 0, 0);"
><property name=
"dao"
>
<ref local=
"userDao"
></ref>
</property></span>
</bean>
<bean id=
"userServiceImplByConstructor"
class
=
"com.jbit.fsd.service.impl.UserServiceImplByConstructor"
>
<!-- 通過定義的單參數構造為業務層的dao屬性賦值 -->
<constructor-arg>
<!-- 引用id為userDao的對象為dao屬性賦值 -->
<ref bean=
"userDao"
/>
</constructor-arg>
</bean>
</beans>
上面的代碼看:local屬性和bean屬性的用法和像,區別在於:當把spring的配置文件拆分為多個時,使用local屬性只能在同一個配文件中檢索Bean的id,而使用bean屬性可以在其他配置文件中檢索id。
<bean id=
"userServiceImpl"
class
=
"com.jbit.fsd.service.impl.UserServiceImpl"
>
<!-- 需要注意是是這裡調用setDao()方法 -->
<property name=
"dao"
>
<bean
class
=
"com.pb.dao.impl.UserDaoimpl"
>
</property> <!-- 屬性注入 -->
</bean>
如果屬性中包含特殊字符如(&,<,>)等可將特殊字符替換為實體引用,如<替換為&It.
<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http:
//www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http:
//www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!-- 以面向接口思想編程實現解耦和 -->
<bean id=
"userDao"
class
=
"com.jbit.fsd.dao.impl.UserDaoImpl"
>
</bean>
<bean id=
"user"
class
=
"com.pb.eneity.User"
>
<property name=
"hobbies"
><br> <!--list類型變量的注入 -->
<list>
<value>足球</value>
<value>籃球</value>
</list>
</property>
</bean>
<bean id=
"user"
class
=
"com.pb.eneity.User"
>
<property name=
"hobbies"
><br> <!--ser類型變量的注入-->
<set>
<value>足球</value>
<value>籃球</value>
</set>
</property>
</bean>
<bean id=
"user"
class
=
"com.pb.eneity.User"
>
<property name=
"hobbies"
><br> <!-- map類型變量的注入 -->
<map>
<entry>
<key><value>username</value></key>
<ref bean=
"com.pb.entity.User"
></ref>
</entry>
</map>
</property>
</bean>
</beans>
使用p命名空間改進配置,改進前先添加p命名空間是聲明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19<?xml version=
"1.0"
encoding=
"UTF-8"
?>
<!--
- Application context definition
for
JPetStore's business layer.
- Contains bean references to the transaction manager and to the DAOs in
- dataAccessContext-local/jta.xml (see web.xml's
"contextConfigLocation"
).
-->
<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
<span style=
"color: rgb(255, 0, 0);"
>xmlns:aop=
"http://www.springframework.org/schema/p"
</span>
xsi:schemaLocation="
http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http:
//www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http:
//www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id=
"userDao"
class
=
"com.jbit.fsd.dao.impl.UserDaoImpl"
<span style=
"color: rgb(255, 0, 0);"
> p:age=
"18"
p:username=
"xiaoming"
</span>>
</bean>
</beans>
使用p命名空間簡化配對效果明顯,使用語法總結:
1.對於直接量(基本數據類型、字符串)屬性,使用方式如下:
p:屬性名=“屬性值”
2.對於引用Bean的屬性,使用方式如下:
p:屬性名-ref="Bean的id"
<bean>元素的autowire屬性提供了一種自動注入的依賴對象的機制,配置Bean時不需要做任何顯示的指定,spring會自動查找符合條件的依賴對象並實施注入。
<bean id="userService" class="com.pb.serviceImp.UserServiceImpl" autowire="byType">
spring提供了幾種自動裝配的類型:
1.no:默認值,Spring默認不進行自動裝配,必須顯示的指定依賴對象
2.byName: 根據屬性名自動裝配,Spring自動查找與屬性名相同的id,如果找到,則自動注入,否則什麼也不做。
3.byType:根據屬性的類型自動裝配,Spring自動查找與屬性類型相同Bean,如果找到唯一的那個,則自動注入,如果找到多個與屬性類型相同的Bean,則拋出異常,如果沒找到則什麼也不做。
4.constructor:和byType類似,不過他針對構造方法,如果spring找到一個Bean和構造方法的參數類型像匹配,則通過構造方法注入到依賴對象,如果沒有,則拋異常。
如果每個Bean都設置autowire屬性也是挺麻煩的,spring提供了default-autowire屬性,設置全局的自動裝配。
1 2 3 4 5 6 7 8 9 10<beans xmlns=
"http://www.springframework.org/schema/beans"
xmlns:xsi=
"http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop=
"http://www.springframework.org/schema/aop"
xmlns:tx=
"http://www.springframework.org/schema/tx"
xmlns:aop=
"http://www.springframework.org/schema/p"
xsi:schemaLocation="
http:
//www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http:
//www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http:
//www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default
-autowire=
"byType"
>