Spring之IOC詳解
學(xué)過Spring的小伙伴對于IOC一定不陌生,IOC:控制反轉(zhuǎn)(Inversion of Control,英文縮寫為IoC)是一個重要的面向?qū)ο缶幊?/a>的法則來削減計算機(jī)程序的耦合問題,也是輕量級的Spring框架的核心。 控制反轉(zhuǎn)一般分為兩種類型,依賴注入(Dependency Injection,簡稱DI)和依賴查找(Dependency Lookup)。依賴注入應(yīng)用比較廣泛。本篇我們通過一個實(shí)例和大家簡單分析一下Spring中IOC的原理,以便我們可以更好的理解Spring。
簡單描述一下我們的場景,添加新用戶到數(shù)據(jù)庫,這里我們采用分層的方式,進(jìn)行功能的實(shí)現(xiàn),我們知道,開發(fā)程序一定要注意程序的可移植性,所以這里簡單為大家介紹一下面向接口編程,面向接口編程就是面向抽象編程、面向規(guī)范編程,它帶來的最大的好處便是解耦、增強(qiáng)擴(kuò)展性、屏蔽變化。

好了下面我們開始我的業(yè)務(wù)實(shí)現(xiàn),首先我們需要創(chuàng)建一個Model--UserDO.java
public class UserDO {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
有了我們的用戶對象,下面我們開始創(chuàng)建Selvect類,Selvect我們知道,使用了接收用戶請求的對象,這里因?yàn)槲覀冎皇菫榱朔奖愦蠹依斫?,所以我們在Selvect中模擬收到用戶請求后進(jìn)行相關(guān)業(yè)務(wù)邏輯處理:
public class UserSelvect {
public static void main(String[] args) {
UserDO userDO = new UserDO();
BeanFactory beanFactory = new ClassPathXmlApplicationContext();//創(chuàng)建我們的Bean工廠
UserService userService = (UserService) beanFactory.getBean("userService");//通過類名來獲得類對象
userService.add(userDO);//完成業(yè)務(wù)邏輯
}
}
一般我們的業(yè)務(wù)邏輯會放在Service層進(jìn)行操作,所以我能先來看一下我們的Service對象:
public class UserService {
private UserDao userDao;//實(shí)例DAO對象
public UserDao getUserDao() {
return userDao;
}
//用于Bean工廠中進(jìn)行DAO動態(tài)綁定
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//用于Selvect對象調(diào)用,進(jìn)行業(yè)務(wù)邏輯處理
public void add(User u){
userDao.add(u);
}
}
下面就是我們的DAO層的實(shí)現(xiàn)了,這里就要說明了,為了最大化提高程序的可移植性,接下來將采用接口編程的實(shí)現(xiàn)進(jìn)行設(shè)計:
/**
* DAO類只有方法定義
* 從而減低程序直接的耦合
*/
public interface UserDao {
public void add(User u);
}
既然是面向接口編程,就一定需要實(shí)現(xiàn)接口的類:
public class UserDaoImpl implements UserDao{
public void add(User u){
System.out.println("保存一個學(xué)生對象");
}
}
好了到這里我們的基本框架已經(jīng)完成,接下來就要開始重點(diǎn)的內(nèi)容了,首先我們需要先了解一些關(guān)于xml解析的知識,在之前的博客中已經(jīng)為大家介紹了過一種方式:Jdom讀取XML文件,不了解的小伙伴可以先移步簡單查看一下,這樣接下來的內(nèi)容,你才不至于感到吃力。下面我們進(jìn)行我們的這個Demo的設(shè)計,首先在src目錄下添加一個Spring.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="userDao" class="com.manyiaby.daoimpl.UserDaoImpl"></bean> <bean id="userService" class="com.manyiaby.service.UserService"> <property name="userDao" bean="userDao"></property> </bean> </beans>
下面我們定義一個Bean工程對象,用來讀取我們的Spring.xml文件,從而完成對象實(shí)例的創(chuàng)建,一便接下來的業(yè)務(wù)操作:
public interface BeanFactory {
public Object getBean(String className);
}
大家是不是發(fā)現(xiàn)我們的Bean工場也是采用接口編程的思想,接下來看一下我們的工場實(shí)現(xiàn)類:
public class ClassPathXmlApplicationContext implements BeanFactory{
private Map<String, Object> beanMap = new HashMap<String, Object>();//用來存配置文件中的類對象
public ClassPathXmlApplicationContext(){
try {
SAXBuilder saxBulder = new SAXBuilder();
Document doc = saxBulder.build(ClassPathXmlApplicationContext.class
.getClassLoader().getResourceAsStream("spring.xml"));
Element root = doc.getRootElement();//獲取根元素
List<Element> list = root.getChildren("bean");
for (Element element : list) {
String id = element.getAttributeValue("id");//得到beanId
String className = element.getAttributeValue("class");//得到Bean的類名地址
System.out.println(className);
Object object = Class.forName(className).newInstance();
beanMap.put(id, object);
if (null != element.getChild("property")) {
Element property = element.getChild("property");
String name = property.getAttributeValue("name");
String beanId = property.getAttributeValue("bean");
Object beanObject = beanMap.get(beanId);//UserDaoImpl
String methodName = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);//setUserDao
System.out.println(methodName);
Method m = object.getClass().getMethod(methodName, beanObject.getClass().getInterfaces()[0]);//UserService的SetUserDao()方法,接收的參數(shù)為UserDao接口類
m.invoke(object, beanObject);//調(diào)用UserService的SetUserDao()方法,傳入UserDaoImpl
}
}
} catch (Exception e) {
System.out.println("" + e);
}
}
//用于類調(diào)用
@Override
public Object getBean(String className) {
return beanMap.get(className);
}
}
簡單為大家介紹一下,我們通過beanMap將我們在Spring中配置的對象,通過反射機(jī)制拿到,然后放置于beanMap對象中,通過getBean方法,共外部類調(diào)用。
上面簡單模擬了一下Spring中IOC的一些內(nèi)容,下面咱們一起來看一下,如何通過Spring完成上面的操作,首先我們需要下載spring.jar,有了這個jar還不夠,spring還依賴commons-logging.jar,好了將這兩個jar包導(dǎo)入到我們的工程中,然后我們就來看一下如何實(shí)現(xiàn)使用:
public class UserSelvect {
public void main() {
UserDO userDO = new UserDO();
BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) beanFactory.getBean("userService");
//ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
//UserService userService = (UserService) context.getBean("userService");
userService.add(userDO);
}
}
其他不用修改,是不是很簡單,好了,關(guān)于Spring的內(nèi)容為大家介紹到這里。
希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!
相關(guān)文章
Spring Cloud實(shí)戰(zhàn)技巧之使用隨機(jī)端口
這篇文章主要給大家介紹了關(guān)于Spring Cloud實(shí)戰(zhàn)技巧之使用隨機(jī)端口的相關(guān)資料,文中介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-06-06
Java中ByteArrayOutputStream亂碼問題解決
本文主要介紹了Java中ByteArrayOutputStream亂碼問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
Java中Controller引起的Ambiguous?mapping問題及解決
這篇文章主要介紹了Java中Controller引起的Ambiguous?mapping問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
springboot+Oauth2實(shí)現(xiàn)自定義AuthenticationManager和認(rèn)證path
本篇文章主要介紹了springboot+Oauth2實(shí)現(xiàn)自定義AuthenticationManager和認(rèn)證path,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
解決IntelliJ IDEA 控制臺輸出中文亂碼問題(史上最簡單)
這篇文章主要介紹了史上最簡單的IntelliJ IDEA 控制臺輸出中文亂碼問題的解決方法,非常不錯,具有一定的參考借鑒價值,需要的朋友參考下吧2018-05-05

