沿着我們上一篇的學習筆記,我們繼續通過代碼學習IOC這一設計思想.
6.Hello類
第一步:首先創建一個類Hello
package cn.sxt.bean;
public class Hello {
private String name;
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("hello,"+name);
}
}
第二步:創建配置文件beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- bean就是java對象,由spring容器來創建和管理 --> <bean name="hello" class="cn.sxt.bean.Hello"> <property name="name" value="張三"></property> </bean> </beans>
第三步:編寫測試類Test
package cn.sxt.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.sxt.bean.Hello;
public class Test {
public static void main(String[] args) {
//解析beans.xml文件生成管理相應的bean對象
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
Hello hello=(Hello)context.getBean("hello");
hello.show();
}
}
我們需要導入相關Jar包(在上一篇筆記Spring主要內容中顯示的那些核心jar包)

此時運行Test程序,會觸發異常:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
我們需要添加commons-logging.jar文件

步驟總結:
1)導入相關jar包
2)編寫spring配置文件(名稱可以自定義)
思考?
Hello對象是誰創建的?
我們在Hello類中添加一個構造函數,可以確定Hello對象確定被創建:
package cn.sxt.bean;
public class Hello {
public Hello() {
System.out.println("hello 被創建");
}
private String name;
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("hello,"+name);
}
}
運行Test測試類結果顯示:
hello 被創建
hello,張三
由此可以得知,Hello對象是由spring容器來創建的:bean工廠,可以包含多個bean,創建不同類的對象
<bean name="hello" class="cn.sxt.bean.Hello"> <property name="name" value="張三"></property> </bean>
Hello對象的屬性是怎樣設置的?
Hello對象的屬性是由spring容器來設置的;
這個過程就叫做控制反轉:
控制的內容:指的是誰來控制對象的創建;傳統的應用程序,對象的創建是由程序本身來控制,使用Spring以后是由spring來創建對象的。
反轉:有反轉就有正轉,正轉指程序來創建對象,反轉指程序本身不去創建對象,而變為被動的接收容器給我們創建的對象
總結:以前對象是由程序本身來創建,使用spring后,程序變為了被動接收spring創建好的對象;
控制反轉有一個別名--依賴注入(DI-dependency injection)
DI:比如在我們的Hello類中,我們的類Hello就依賴於name屬性,以來的這個name屬性是由spring容器來設置的,name值的設置過程就叫做依賴注入(通過setName方法進行的依賴注入)
Ioc--是一種編程思想,由主動編程變為別動接收;
Ioc的實現是通過Ioc容器(Bean工廠)來實現的。Ioc容器--BeanFactory
在第一篇學習筆記中的UserDao和UserDaoService的例子,我們在這里就可以使用spring配置文件的方式來管理對象的生命周期以及依賴對象的注入;
beanx.xml修改如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- bean就是java對象,由spring容器來創建和管理 --> <bean id="mysqlDao" class="cn.sxt.dao.impl.UserDaoMySqlImpl"></bean> <bean id="oracleDao" class="cn.sxt.dao.impl.UserDaoOracleImpl"></bean> <bean id="service" class="cn.sxt.service.impl.UserServiceImpl"> <!-- ref引用對象(對象是由spring來創建的) --> <property name="userDao" ref="mysqlDao"></property> </bean> <!-- property如何設置:name="setUserDao(去除set,並將剩余的UserDao首字母小寫)" --> </beans>
當我們需要替換具體的實現時,就可以直接在配置文件中進行修改,例如將ref="mysqlDao"修改為ref="oracleDao";
在測試類中我們就可以這樣來組織代碼:
package cn.sxt.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.sxt.service.UserService;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
UserService us=(UserService)ac.getBean("service");
us.getUser();
}
}
使用IOC來創建對象的方式:3種方式
1)通過無參的構造方法來創建;
User.java:
package cn.sxt.vo;
public class User {
public User(){
System.out.println("user的無參構造方法");
}
private String name;
public void setName(String name) {
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
}
beans.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="cn.sxt.vo.User"> <property name="name" value="張三"></property> </bean> </beans>
Test:
package cn.sxt.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.sxt.vo.User;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
User user=(User)ac.getBean("user");
user.show();
}
}
2)通過有參構造方法來創建;
User.java:
package cn.sxt.vo;
public class User {
private String name;
public User(String name) {
super();
this.name = name;
}
public void show(){
System.out.println("name="+name);
}
}
beans.xml配置(有三種情況):
第一種:根據參數的下標(index)來設置;
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="user" class="cn.sxt.vo.User"> <!-- index指的是構造方法參數下標,從0開始 --> <constructor-arg index="0" value="李四"></constructor-arg> </bean> </beans>
第二種:根據參數名稱(name)來設置;
<bean id="user" class="cn.sxt.vo.User"> <!-- name指的是屬性值 --> <constructor-arg name="name" value="王五"></constructor-arg> </bean>
第三種:根據參數類型(type)來設置;
<bean id="user" class="cn.sxt.vo.User"> <constructor-arg type="java.lang.String" value="徐六"></constructor-arg> </bean>
3)通過工廠方法來創建對象(有兩種);
第一種:靜態工廠來創建;
UserFactory.java:
package cn.sxt.factory;
import cn.sxt.vo.User;
public class UserFactory {
public static User newInstance(String name){
return new User(name);
}
}
beans.xml配置:
<bean id="user" class="cn.sxt.factory.UserFactory" factory-method="newInstance"> <constructor-arg index="0" value="任七"></constructor-arg> </bean>
第二種:動態工廠來創建
UserDynamicFacory.java:
package cn.sxt.factory;
import cn.sxt.vo.User;
public class UserDynamicFactory {
public User newInstance(String name){
return new User(name);
}
}
beans.xml:
<bean id="userFacotry" class="cn.sxt.factory.UserDynamicFactory"/> <bean id="user" factory-bean="userFacotry" factory-method="newInstance"> <constructor-arg index="0" value="王五"/> </bean>
