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">