*注:在IDEA中我建立的Maven項目,不瞭解Maven的朋友能夠看我以前的博客「咱們一塊兒走進Maven——知己知彼」,瞭解Maven後能夠看我以前的博客「Maven的安裝與配置」,自行安裝,行動起來吧。html
在pom.xml文件中添加Spring依賴和日誌相關依賴java
<dependencies> <!--測試相關--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--Spring核心基礎依賴--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--日誌相關--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
在main目錄下面建立java和resources目錄web
建立dao包,在dao包下建立TestDao接口和TestDao接口的實現類,結構以下圖:正則表達式
TestDao接口代碼示例:spring
package dao; public interface TestDao { public void sayHello(); }
TestDaoImpl實現類代碼示例:express
package dao; public class TestDaoImpl implements TestDao{ @Override public void sayHello() { System.out.println("Hello,Spring!"); } }
在resources資源目錄點擊右鍵,依次選擇New-->XML Configuration File-->Spring Config,建立applicationContext.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"> <!--把testDao對象的建立權交給Spring-->
<!-- <bean> 配置須要建立的對象
id :用於以後從Spring容器中得到實例時使用的
class :須要建立實例的全限定類名-->
<bean id="testDao" class="dao.TestDaoImpl"></bean> </beans>
建立test包,在test包下建立測試類SpringTest api
package test;
import dao.TestDao; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest {
@Test
public void demo1(){
// 以前開發,本身手寫new出對象
TestDao dao= new TestDaoImpl();
dao.sayHello();
}
@Test
public void demo2() {
// 如今從spring容器中得到對象實例
// 1 、得到容器
//初始化Spring容器ApplicationContext,加載配置文件
ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
// 二、得到內容 ,注意此時不須要本身new出對象了,都是從spring容器中得到
//經過容器獲取testDao實例
TestDao testDao = (TestDao) application.getBean("testDao");
testDao.sayHello();
}
}
點擊測試方法左側的運行按鈕,選擇Run,測試代碼數組
運行後控制檯顯示結果 app
項目運行成功!!!!!!!
class B { private A a; // B類依賴A類,B類使用A類。 } 依賴:一個對象須要使用另外一個對象。 注入:經過setter方法進行另外一個對象實例設置。
例如:
class BookServiceImpl { // 以前開發:接口 = 實現類(service和dao耦合了,寫死了,知道具體的實現類是誰,那麼個人具體實現類變化,那麼這行代碼也得跟着變) // private BookDao bookDao = new BookDaoImpl(); // spring以後(解耦:service實現類使用了dao的接口,這樣就不知道具體的實現類是誰了) private BookDao bookDao; setter方法 } 模擬spring執行過程 建立service實例:BookService bookService = new BookServiceImpl(); => IoC <bean> 建立dao實例:BookDao bookDao = new BookDaoImple(); => IoC 將dao設置給service:bookService.setBookDao(bookDao); => DI <property>
具體代碼實現:
實現步驟:
項目結構:
加載依賴:
在pom.xml文件中添加Spring依賴和日誌相關依賴
<dependencies> <!--測試相關--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--Spring核心基礎依賴--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!--日誌相關--> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>
BookDao接口和實現類
package dao; public interface BookDao { void save(); }
package dao; public class BookDaoImpl implements BookDao { @Override public void save() { System.out.println("實現添加功能"); } }
BookService接口和實現類
package Service; public interface BookService { void addBook(); }
package Service; import dao.BookDao; import dao.BookDaoImpl; public class BookServiceImpl implements BookService { //方式一:以前,接口=實現類 //private BookDao bookDao= new BookDaoImpl(); //方式二:如今,接口+setter方法 private BookDao bookDao; public void setBookDao(BookDao bookDao){ this.bookDao=bookDao; } @Override public void addBook() { this.bookDao.save(); } }
將dao和service配置到 applicationContext.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 :用於以後從Spring容器中得到實例時使用的 class :須要建立實例的全限定類名--> <!-- 模擬spring執行過程 建立service實例:BookService bookService = new BookServiceImpl(); => IoC <bean> 建立dao實例:BookDao bookDao = new BookDaoImple(); => IoC 將dao實例設置給service實例:bookService.setBookDao(bookDao); => DI <property> <property> 用於進行屬性注入 name : Bean的屬性名稱,經過setter方法得到 setBookDao => BookDao => bookDao ref :另外一個Bean的id值的引用 --> <!-- 建立service實例 --> <bean id="bookServiceId" class="Service.BookServiceImpl"> <!-- 將dao實例設置給service實例 --> <property name="bookDao" ref="bookDaoId"></property> <!-- 用於進行屬性注入 --> </bean> <!-- 建立dao實例 --> <bean id="bookDaoId" class="dao.BookDaoImpl"></bean> </beans>
使用api測試
建立test包,在test包下建立測試類SpringTest
package test; import Service.BookService; import org.junit.jupiter.api.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { @Test public void Test1(){ // 以前開發,本身手寫new出對象 // BookService bookService = new BookServiceImpl(); // bookService.addBook(); } @Test public void Test2(){ // 如今從spring容器中得到對象實例 // 1 、得到容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 二、得到內容 ,注意此時不須要本身new出對象了,都是從spring容器中得到 BookService bookService = (BookService) applicationContext.getBean("bookServiceId"); bookService.addBook(); } }
運行後控制檯顯示結果
這就成功了,開心一下,經過這兩個案例,多Spring有了初步的理解,加油!
api總體瞭解便可,以後不使用,在學習過程須要。
工廠
,用於生成任意Bean。採起延遲加載,第一次調用getBean(); 時纔會初始化Bean。(即實例化對象)
採起非延時加載,當配置文件被加載時,就進行對象的實例化。
示例代碼以下:
package test; import Service.BookService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; public class SpringTest { @Test public void Test1(){ // 以前開發,本身手寫new出對象 // BookService bookService = new BookServiceImpl(); // bookService.addBook(); } @Test public void Test2(){ // 如今從spring容器中得到對象實例 // 1 、得到容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 採起非延時加載,當配置文件被加載時,就進行對象的實例化。 // 二、得到內容 ,注意此時不須要本身new出對象了,都是從spring容器中得到 BookService bookService = (BookService) applicationContext.getBean("bookServiceId"); bookService.addBook(); } @Test public void demo3() { // 如今從spring容器中得到對象實例,使用的是BeanFactory,裏面須要一個Resource,該Resource又是一個接口,須要找它的實現類ClassPathResource // 1 、得到容器 BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); // 二、得到內容 ,注意此時不須要本身new出對象了,都是從spring容器中得到 BookService bookService = (BookService) beanFactory.getBean("bookServiceId"); // 採起延遲加載,第一次調用getBean(); 時纔會初始化Bean(即實例化對象)。 bookService.addBook(); } }
3種bean實例化方式:
使用默認構造方法實例化
格式:
<bean id="從Spring容器中得到實例時使用的" class="須要建立實例的全限定類名"></bean> 例如:<bean id="userServiceId" class="Service.UserServiceImpl"></bean>
示例中用到的 UserService.java 和 UserServiceImpl.java 代碼同上面實例中的代碼,這裏再也不贅述!
在spring容器中進行配置:
applicationContext.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 的方式 :使用默認構造方法實例化,即要實例化的Bean必需要提供默認構造方法 -->
<bean id="userServiceId" class="Service.UserServiceImpl"></bean>
</beans>
測試代碼:
public class TestIoC { @Test public void demo01() { // 以前開發,本身手寫new出對象 UserService userService = new UserServiceImpl(); // 直接手動建立實例 userService.addUser(); } @Test public void demo02() { // 如今從spring容器中得到對象實例 // 1 、得到容器 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 二、得到內容 ,注意此時不須要本身new出對象了,都是從spring容器中得到 UserService userService = (UserService) applicationContext.getBean("userServiceId"); userService.addUser(); } }
使用`靜態工廠方法`實例化
示例中用到的 UserService.java 和 UserServiceImpl.java 代碼同上面實例中的代碼,這裏再也不贅述!
格式:
<bean id="" class="工廠全限定類名" factory-method="靜態方法名稱">
在spring容器中進行配置:
applicationContext.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 的方式 :使用靜態工廠方法實例化
將自定義的靜態工廠建立的實例交給spring管理
class 自定義靜態工廠全限定類名
factory-method 靜態方法名
-->
<bean id="userServiceId" class="Service.MyBeanFactory" factory-method="createService"></bean>
</beans>
靜態工廠類代碼:
public class MyBeanFactory { /** * 建立實例的靜態工廠,全部的方法必須是靜態的(static)。 * * @return */ public static UserService createService() { return new UserServiceImpl(); } // 還有建立其餘實例的靜態工廠 // ...... }
測試代碼:
TestStaticFactory.java
/** * 第二種實例化Bean 的方式 :使用靜態工廠方法實例化 * */ public class TestStaticFactory { @Test public void demo01() { // 之前:使用自定義的靜態實例工廠 UserService userService = MyBeanFactory.createService(); userService.addUser(); } @Test public void demo02() { // 如今:使用spring 工廠:將自定義的靜態工廠建立的實例交給spring管理
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = applicationContext.getBean("userServiceId", UserService.class); // 這種方式底層會自動轉換
// UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
}
}
注意:當使用JDK版本爲1.8時,運行上面的測試代碼會出現一個問題: java.lang.IllegalArgumentException,
問題解決連接:使用Junit測試一個 spring靜態工廠實例化bean 的例子,全部代碼都沒有問題,可是出現java.lang.IllegalArgumentException異常
小結:在之後的開發中,工廠類不須要咱們去手寫,由於別人已經寫好了,咱們經過編寫配置文件
,把別人寫好的工廠類拿來,寫上要用的方法名,而後把它生產後的實例給Spring存起來,之後咱們要用什麼實例,跟Spring說一下,去拿就能夠了。
使用`實例工廠方法`實例化
實例工廠:必須先有工廠的實例對象,而後經過實例對象去建立對象。特色:提供全部的方法都是「非靜態」的。
示例中用到的 UserService.java 和 UserServiceImpl.java 代碼同上面實例中的代碼,這裏再也不贅述!
在spring容器中進行配置:
applicationContext.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 的方式 :使用實例工廠方法實例化 -->
<!--建立工廠實例 -->
<bean id="myBeanFactoryId" class="com.itheima.c_inject.c_factory.MyBeanFactory" ></bean>
<!--經過工廠實例,得到對象 factory-bean 工廠實例名稱 factory-method 普通方法名稱 -->
<bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createService"></bean>
</beans>
靜態工廠類代碼:
public class MyBeanFactory { /** * 建立實例的工廠,全部方法非靜態 * * @return */ public UserService createService() { return new UserServiceImpl(); } // 還有建立其餘實例的工廠 // ...... }
測試代碼:
TestFactory.java
package test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 第三種實例化Bean 的方式 :使用實例工廠方法實例化 * */ public class TestFactory { @Test public void demo01() { // 之前:使用自定義的實例工廠 // 一、建立工廠實例 MyBeanFactory myBeanFactory = new MyBeanFactory(); // 二、經過工廠實例,得到對象 UserService userService = myBeanFactory.createService(); userService.addUser(); } @Test public void demo02() { // 如今:使用spring 工廠:將自定義的實例工廠建立的實例交給spring管理
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = applicationContext.getBean("userServiceId", UserService.class); // 這種方式底層會自動轉換
// UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
}
}
普通bean :以前操做的都是普通bean。例如:< bean id="xxx" class="A" >
,這句代碼的意思是:Spring直接建立A的實例,並返回。
FactoryBean :是一個特殊的bean,具備工廠生成對象能力
,可是隻能生成特定的對象。
想要生產對象的bean 必須實現FactoryBean 接口,此接口提供方法getObject(); 用於得到特定bean。
< bean id="xxx" class="FB">
,這句代碼的意思是:Spring會先建立FB實例,而後調用getObject(); 方法,並返回方法的返回值。BeanFactory 和 FactoryBean 對比?
< bean id="xxx" class="….ProxyFactoryBean">
,這句代碼的意思是:得到代理對象的實例。即AOP使用。spring容器中bean元素id和name屬性的區別?
在spring容器中添加如下配置:
示例:< bean id="userServiceId" class="com.itheima.a_ioc.UserServiceImpl">
bean節點中id和name的區別:
區別一:
區別二:
id :id的命名要知足XML對ID屬性命名規範
例如:必須以字母開始,可使用字母、數字、連字符、下劃線、句話、冒號
name : 若是Bean的名稱中含有特殊字符,就須要使用name屬性
例如 : < bean name="# boy" class="cn.itheima.ioc.Boy"/>
由於name屬性能夠相同,因此後出現Bean會覆蓋以前出現的同名的Bean。
總結:項目開發的時候,強烈要求用id,由於id能夠表示惟一引用。
Bean 的做用域:用於肯定spring所建立bean 的實例個數。
lazy-init="true"
來延遲初始化bean,這時候,只有第一次獲取bean會才初始化bean。
< bean id="xxx" class="service.UserServiceImpl" lazy-init="true">
default-lazy-init="true"
,< beans default-lazy-init="true「>
在spring容器中進行配置:
applicationContext.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="userServiceId" class="com.itheima.d_scope.UserServiceImpl" scope="prototype"></bean>
</beans>
測試代碼:
TestScope.java
public class TestScope { @Test public void demo01() { // 如今:使用spring 工廠
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService1 = applicationContext.getBean("userServiceId", UserService.class);
// 這種方式底層會自動轉換
UserService userService2 = applicationContext.getBean("userServiceId", UserService.class);
// 這種方式底層會自動轉換
// 默認Bean的做用域是單例,因此打印的對象的地址是同樣的
// System.out.println(userService1); // service.UserServiceImpl@2ac273d3
// System.out.println(userService2); // service.UserServiceImpl@2ac273d3
// 如今在配置文件中添加scope屬性,值爲prototype,此時Bean的做用域變爲多例了,再次打印,輸出地址不同了
System.out.println(userService1);
//service.UserServiceImpl@66480dd7
System.out.println(userService2);
//service.UserServiceImpl@52a86356
}
}
setBeanName
。setBeanFactory
)或者上下文對象(setApplicationContext
)。postProcessBeforeInitialization
。afterPropertiesSet
。
,則表示指定初始化方法 init
。postProcessAfterInitialization
。destroy
。
,則表示指定銷燬方法 customerDestroy
。
目標方法執行前和執行後,將進行Bean的初始化或銷燬。
示例:<bean id="xxx" class="xxx" init-method="初始化的方法名稱" destroy-method="銷燬的方法名稱"></bean>
示例代碼以下:
編寫目標類代碼:
UserService.java
public interface UserService { void addUser(); }
UserServiceImpl.java
public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("e_lifecycle add user"); } public void myInit() { System.out.println("個人初始化方法"); } public void myDestory() { System.out.println("個人銷燬方法"); } }
在spring容器中進行配置:
applicationContext.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">
<!--
init-method 用於配置初始化方法,用於準備數據等使用場景
destroy-method 用於配置銷燬方法,用於清理資源等使用場景
-->
<bean id="userServiceId" class="service.UserServiceImpl"
init-method="myInit" destroy-method="myDestory"></bean>
</beans>
編寫測試代碼:
public class TestLifecycle { @Test public void demo01() throws Exception { // 如今:使用spring 工廠(spring 容器)
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser(); // 要想使個人銷燬方法也執行,必需要求:
// 1.容器必須先close,個人銷燬方法纔會執行;
// 2.必須是單例的(spring所建立該bean的實例個數只有一個)即bean中的scope配置成默認便可。
// 由於此close方法在接口 ApplicationContext 中沒有定義,而在實現類中提供了該方法,咱們可使用反射,由於反射最後執行的就是實現類中的方法。
applicationContext.getClass().getMethod("close").invoke(applicationContext); } }
這句代碼的意思就是:把實現類提供給了spring容器。咱們來模擬這句話的意思:
before() => postProcessAfterInitialization(Object bean, String beanName) after() => postProcessBeforeInitialization(Object bean, String beanName) A a = new A(); a = B.before(a); // 將a的實例對象傳遞給後處理bean,能夠什麼都沒作,也能夠作一些事情,好比:生成jdk代理對象並返回給a,這樣a就從實例對象變成代理對象了,此時的a就具備了AOP功能;再好比,若是把null返回給a,再用a去調用方法,就會出現空指針異常。 a.init(); a = B.after(a); // 如下是AOP演示: // 咱們如今在後處理Bean 代碼執行完以後,把jdk代理對象返回給a。讓a在調用addUser()以前先作一些事情 // 以前要作的事情 a.addUser(); // 在目標方法的先後能夠作一些事情,例如:開啓事務、提交事務、性能監控(先後時間)等等 // 以後要作的事情 a.destroy();
目標類示例代碼以下:
UserService.java
public interface UserService { void addUser(); }
UserServiceImpl.java
public class UserServiceImpl implements UserService { @Override public void addUser() { System.out.println("e_lifecycle add user"); } public void myInit() { System.out.println("個人初始化方法"); } public void myDestory() { System.out.println("個人銷燬方法"); } }
實現類示例代碼以下:
MyBeanPostProcessor.java
public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("執行了前方法:" + beanName); return bean; } @Override public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { System.out.println("執行了後方法:" + beanName); // 傳入的參數bean是咱們的目標對象,此時咱們的目標對象只有一個接口,那麼咱們的代理對象也只有一個接口 // 生成jdk代理對象 return Proxy.newProxyInstance( MyBeanPostProcessor.class.getClassLoader(), // 代理對象 bean.getClass().getInterfaces(), // 目標對象 new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("---開啓事務---"); Object obj = method.invoke(bean, args); // 執行目標方法,本例中的目標方法是addUser System.out.println("---關閉事務---"); return obj; } }); // 代理的處理程序 } }
在spring容器中進行配置:
applicationContext.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">
<!--
init-method 用於配置初始化方法,用於準備數據等使用場景
destroy-method 用於配置銷燬方法,用於清理資源等使用場景
-->
<bean id="userServiceId" class="service.UserServiceImpl"
init-method="myInit" destroy-method="myDestory"></bean>
<!-- 將後處理的實現類註冊給spring -->
<bean class="com.itheima.e_lifecycle.MyBeanPostProcessor"></bean>
</beans>
測試示例代碼以下:
TestLifecycle.java
public class TestLifecycle { @Test public void demo01() throws Exception { // 如今:使用spring 工廠(spring 容器) ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService) applicationContext.getBean("userServiceId");
userService.addUser();
// 要想使個人銷燬方法也執行,必需要求:
// 1.容器必須先close,個人銷燬方法纔會執行;
// 2.必須是單例的(spring所建立該bean的實例個數只有一個)即bean中的scope配置成默認便可。
// 由於此close方法在接口 ApplicationContext 中沒有定義,而在實現類中提供了該方法,咱們可使用反射,由於反射最後執行的就是實現類中的方法。
applicationContext.getClass().getMethod("close").invoke(applicationContext);
}
}
手工裝配
或自動裝配
。在實際應用中
建議使用手工裝配
,由於自動裝配會產生未知狀況,開發人員沒法預見最終的裝配結果。
Bean對象類:
public class User { private Integer uid; private String username; private Integer age; public User(Integer uid, String username) { // 構造方法一 super(); this.uid = uid; this.username = username; } public User(String username, Integer age) { // 構造方法二 super(); this.username = username; this.age = age; } // 省略getter 和 setter 方法 // ......
在spring容器中進行配置:
applicationContext.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">
<!--6.5.一、構造方法注入
<constructor-arg> 用於配置構造方法的一個參數argument
name :參數的名稱
value :設置普通數據
ref :設置引用數據,通常是另外一個bean 的id值
index :參數的索引號,從0開始 。若是隻有索引,匹配到了多個構造方法時,默認使用第一個。
type :肯定參數類型
例如1:name屬性開發中不經常使用,由於使用該屬性須要關聯要實例化對象的源碼,不然name的值你就不知道。而通常開發中咱們咱們不會獲得源碼。
<constructor-arg name="username" value="李曉藝"></constructor-arg>
<constructor-arg name="age" value="26"></constructor-arg>
例如2:類型type 和 索引index (這二者結合使用)
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
注意:在開發中爲了指定執行的是哪一個構造方法,通常使用index屬性和type屬性結合的方式。
-->
<bean id="userId" class="entity.User">
<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
</bean>
</beans>
在spring容器中進行配置:
applicationContext.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">
<!--6.5.二、setter方法注入
* 注入的是普通數據 時
<property name="" value="值"></property>
等效
<property name="">
<value>值</value>
</property>
* 注入的是引用數據時
<property name="" ref="另外一個bean的id"></property>
等效
<property name="">
<ref bean="另外一個bean的id"></ref>
</property>
-->
<bean id="personId" class="entity.Person">
<property name="pname" value="曉藝"></property>
<property name="age">
<value>26</value>
</property>
<property name="homeAddr" ref="homeAddrId"></property>
<property name="companyAddr">
<ref bean="companyAddrId"></ref>
</property>
</bean>
<bean id="homeAddrId" class="entity.Address">
<property name="addr" value="山西運城"></property>
<property name="tel" value="911"></property