Spring框架學習筆記1-----IoC、DI

目錄

1、Spring框架概述

2、IOC 

2.1、導入jar包

2.2、目標類

2.3、配置文件

2.4、測試

3、DI

3.1、依賴注入

3.2、配置信息

3.3、舉例說明 

4、核心API 、

4.1、BeanFactory:

4.2、ApplicationContext:

5、裝配Bean基於XML

5.1、實例化方式(三種)

5.1.1、默認構造

5.1.2、靜態工廠及其測試:

5.1.3、實例工廠及其測試

5.2、Bean的種類

5.2.1、普通Bean:

5.2.2、FactoryBean:

5.2.3、BeanFactory 和FactoryBean對比:

5.3、作用域

5.3.1、作用域:

5.3.2、取值:

5.3.3、配置信息:

5.3.4、測試 

4、Bean的生命週期

5.4.1、初始化和銷燬及其測試

5.4.2、BeanPOSTProcessor後處理Bean

5、屬性依賴注入

5.5.1、構造方法(之後再補充)

5.5.2、setter方法

5.5.3、P命令空間[瞭解]

5.5.4、SpEL(瞭解)

6、集合注入(Array、List、Set、Map、Properties)

6、裝配Bean基於註解

6.1、什麼是註解

6.2、註解分類

6.3、生命週期

6.4、作用域

7、註解和xml混合使用


 

1、Spring框架概述

2、IOC 

2.1、導入jar包

四個核心(beans、core、context、expression)和一個依賴(commons.logging)

2.2、目標類

在之前的學習中,通常通過new實例化對象,學習spring框架後,將由spring創建對象的實例,即IoC(Inverse of control,控制反轉)

創建UserService接口和其實現類

public interface UserService {
	public void addUser();
}
public class UserServiceImpl implements UserService{
	@Override
	public void addUser() {
		// TODO 自動生成的方法存根
		System.out.println("test of ioc");
	}
}

2.3、配置文件

<?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 definitions here
	<bean>這個標籤配置的是我們需要創建的對象
	     id:用於之後從Spring容器獲得實例時使用
		 class:需要創建實例時的全限定名
	-->
	<bean id="UserServiceId" class = "test_ioc.UserServiceImpl" ></bean>
</beans>

2.4、測試

public class TestIoC {
	@Test
	public void demo01() {
		//之前學習的是以下方式new實例對象
		UserService userService = new UserServiceImpl();
		userService.addUser();
	}
	
	@Test
	public void demo02() {
		/*
		 * 從Spring容器中獲得實例對象
		 * 1、獲取容器
		 * 2、獲得內容
		 */
		//1、獲取容器
		String xmlPath = "applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		//2、獲取內容:不需要自己new 都是從spring容器中獲得
		
		UserService userService = (UserService) applicationContext.getBean("UserServiceId");
		userService.addUser();
	}

}

結果如下:

3、DI

3.1、依賴注入

依賴:一個對象需要使用到另一個對象注入:通過setter方法進行另一個對象實例設置

class B{
    private A a;
    setter方法;
};//B中有一個成員變量a,稱爲B依賴於A 

3.2、配置信息

<bean id = "" class = "">
    <property name = "" ref = ""></property>
</bean>
<property>標籤:用於進行屬性注入
name :bean的屬性名,通過setter方法獲得
ref:另一個bean的id值的引用

 

3.3、舉例說明 

1、目標類:dao、service

  • 創建BookService接口和實現類
  • 創建BookDao接口和實現類
public interface BookDao {
	public void addBook();
}

public class BookDaoImpl implements BookDao {
	@Override
	public void addBook() {
		// TODO 自動生成的方法存根
		System.out.println("di add book");
	}
}

public interface BookService {
	public void addBook();
}

public class BookServiceImpl implements BookService {
	//方式一:接口+實現類
	//private BookDao bookDao = new BookDaoImpl();
	//方式二:接口+setter
	private BookDao bookDao;
	//setter方法
	public void setBookDao(BookDao bookDao) {
		this.bookDao = bookDao;
	}
	@Override
	public void addBook() {
		// TODO 自動生成的方法存根
		this.bookDao.addBook();
	}
}

2、配置文件

  • 將dao和service配置到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 definitions here
	模擬spring的執行過程
	創建service實例:BookService bookService = new BookServiceImpl();   IoC   (<bean>)
	創建dao實例:BookDao bookDao = new BookDaoImpl();   IoC   (<bean>)
	將dao設置給service:bookService.setBookDao(bookDao);   DI   (<property>)
	<property>標籤:用於進行屬性注入
		name :bean的屬性名,通過setter方法獲得
			bookDao
		ref:另一個bean的id值的引用
			bookDaoId
	-->
	<!-- 創建service-->
	<bean id="bookServiceId" class="test_di.BookServiceImpl">
		<property name="bookDao" ref="bookDaoId"></property>
	</bean>
	<!-- 創建dao-->
	<bean id="bookDaoId" class = "test_di.BookDaoImpl"></bean>
	
</beans>

3、測試

public class TestDi {
	@Test
	public void demo() {
		//從spring容器中獲得
		String xmlPath = "test_di/applicationContext.xml";
		ApplicationContext applicationcontext= new ClassPathXmlApplicationContext(xmlPath);
		BookService bookService = (BookService) applicationcontext.getBean("bookServiceId");
		bookService.addBook();
	}
}

 

4、核心API 、

4.1、BeanFactory:

工廠,用於生成任意bean。採取延遲加載,第一次getBean時會初始化Bean

4.2、ApplicationContext:

是BeanFactory的子接口,功能更加強大(國際化處理、事件傳遞、Bean自動裝配、各種不同應用層的Context實現)。當配置文件被加載就進行了對象的實例化

  1. ClassPathXmlApplicationContext:用於加載classpath(類路徑,src)下的xml
  2. FileSystemXmlApplicationContext:用於加載指定盤符下的xml

5、裝配Bean基於XML

5.1、實例化方式(三種)

5.1.1、默認構造

<bean id="" class=""></bean>;
              --->必須提供默認構造(就是沒有寫構造方法時系統默認的無參構造)

5.1.2、靜態工廠及其測試:

  1. 常用於Spring整合其他框架(工具)
  2. 用於生產實例對象,所有的方法必須是static

配置信息

<bean id="" class="工廠的全限定類名" factory-method="靜態方法"></bean>

測試 

 之前的學習的靜態工廠:

//People接口
public interface People {
	public void newPeople();
}
//People接口的實現類
public class PeopleImpl implements People {
	@Override
	public void newPeople() {
		// TODO 自動生成的方法存根
		System.out.println("create a people");
	}
}

//靜態工廠
public class MyBeanFactory {

	public static People createPeople() {
		return new PeopleImpl();
	}

}

//靜態工廠測試
public class TestStaticFactory {
	@Test
	public void demo01() {
		People people = MyBeanFactory.createPeople();
		people.newPeople();
	}
}

 學習Spring後:

//測試類如下
public class TestStaticFactory {
	@Test
	public void demo02() {
		//Spring工廠
		String xmlPath = "test_b_inject_static_factory/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("People",People.class);
		people.newPeople();
	}
}

 spring配置信息:(主要是寫配置信息)

<?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 definitions here-->
    <!--  將靜態工廠創建的實例教育spring 
    class:確定靜態工廠全限定名
    factory-method:確定靜態方法名
    -->
    <bean id="People" class = "test_b_inject_static_factory.MyBeanFactory" factory-method="createPeople"></bean>
</beans>

5.1.3、實例工廠及其測試

  1. 必須現有工廠的實例對象,然後通過實例對象去創建對象。
  2. 提供的所有方法是非靜態的

配置信息

<bean id = "" factory-bean = "實例工廠" factory-method = "普通方法"></bean>

測試

 之前的學習

//People類接口
public interface People {
	public void newPeople();
}
//People類的實現類
public class PeopleImpl implements People{
	@Override
	public void newPeople() {
		// TODO 自動生成的方法存根
		System.out.println("create a people");
	}
}
//實例工廠
public class MyBeanFactory {
	public People createPeople() {
		return new PeopleImpl();
	}
}
//測試類
public class TestFactory {
	@Test
	public void demo01() {
		//1、創建工廠
		MyBeanFactory myBeanFactory = new MyBeanFactory();
		//2、通過工廠實例獲取對象
		People people = myBeanFactory.createPeople();
		people.newPeople();
	}
}

學習spring後 

public class TestFactory {
	@Test
	public void demo02() {
		String xmlPath = "test_c_inject_factory/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("People",People.class);
		people.newPeople();
	}
}

spring配置信息 

<?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 definitions here-->
    <!-- 創建工廠實例 -->
    <bean id = "MyBeanFactory" class = "test_c_inject_factory.MyBeanFactory" ></bean>
    <!-- 獲得People 
    factory-bean:獲得工廠實例
    factory-method:確定普通方法的
    -->
    <bean id = "People" factory-bean = "MyBeanFactory" factory-method="createPeople"></bean>
</beans>

測試結果

 

5.2、Bean的種類

5.2.1、普通Bean:

之前的操作都是普通bean,<bean id="" class="A">,spring直接創建A的實例,並返回

5.2.2、FactoryBean:

是一個特殊的bean,具有工廠生成對象的能力,只能生成特定的對象。bean必須實現FactoryBean的接口,此接口提供一個方法getObject()用於獲得特定的bean。-----<bean id="" class="FB">,先創建FB實例,然後調用getObject()方法,並返回方法的返回值

5.2.3、BeanFactory 和FactoryBean對比:

BeanFactory是工廠,用於生成任意Bean,FactoryBean是特殊的bean,用於生成另一個特定的bean。例如ProxyFactoryBean,此工廠bean用於生產代理,<bean id="" class="...ProxyFactoryBean">獲得代理對象實例。AOP使用

5.3、作用域

5.3.1、作用域:

用於確定spring創建bean實例個數

類別 說明
singleton 在Spring IoC容器中僅存在一個Bean實例,Bean以單例方式存在
prototype 每次從容器中調用Bean時,都返回一個新的實例,即每次調用getBean()時,相當於執行new XxxBean()
request 每次HTTP請求都會創建一個新的Bean,僅適用於webApplicationContext環境
session 同一個HTTP Session共享一個Bean,不同Session使用不同Bean,僅適用於webApplicationContext環境
globalSession 一般用於Portlet應用環境,該作用域僅適用於webApplicationContext環境

5.3.2、取值:

                     singleton:單例,默認情況下是單例模式

                     prototype:多例,每執行一次getBean()獲得一次實例

5.3.3、配置信息:

<bean id="" class="" scope="取值"></bean>
單例模式:
<bean id="People" class = "PeopleImpl"></bean>
多例模式:
<bean id="People" class = "PeopleImpl" scope = "prototype"></bean>

5.3.4、測試 

測試如下代碼運行結果分別如下:

//People和PeopleImpl與上述相同
public class TestFactory {
	@Test
	public void demo01() {
		String xmlPath = "test_d_scope/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people1 = applicationContext.getBean("People",People.class);
		People people2 = applicationContext.getBean("People",People.class);
		System.out.println(people1);
		System.out.println(people2);
	}
}

4、Bean的生命週期

5.4.1、初始化和銷燬及其測試

  • 目標方法執行前會執行初始化方法
  • 執行銷燬方法的兩點要求:
  1. 容器必須close,才執行銷燬方法
  2. 必須是單例模式(默認情況下就是單例模式)
<bean id = "" class = "" init-method = "初始化的方法名" destory-method = "銷燬的方法名稱">
init-method:用於配置初始化方法,準備數據
destroy-method:用於配置銷燬方法,清理資源等

測試代碼:在PeopleImpl類中添加初始化和銷燬方法

public class PeopleImpl implements People {
	@Override
	public void newPeople() {
		// TODO 自動生成的方法存根
		System.out.println("create a people");
	}
	//初始化方法
	public void myInit() {
		System.out.println("my init method");
	}
	//銷燬方法
	public void myDestroy() {
		System.out.println("my destroy method");
	}
}

配置文件

<?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 = "People" class = "test_e_lifecycle.PeopleImpl" init-method = "myInit" destroy-method = "myDestroy"></bean>
	
</beans>

 測試類

public class TestFactory {
	@Test
	public void demo01() throws Exception, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		String xmlPath = "test_e_lifecycle/applicationContext.xml";
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("People",People.class);
		people.newPeople();
		//要求1、容器必須close,銷燬方法才執行 2、必須是單例模式
		//applicationContext.getClass().getMethod("close").invoke(applicationContext);
		//此ApplicationContext接口中沒有定義close()方法,但其實現類提供
		applicationContext.close();
	}
}

測試結果:

5.4.2、BeanPOSTProcessor後處理Bean

  • spring提供的一種機制,只要去實現此接口BeanPostProcessor,並將實現類提供給spring容器,spring容器將自動的執行,在初始化方法前執行before(),在初始化方法後執行after()
  • Factory hook(鉤子)that allows for custom modification of new instances,e.g.checking for marker interfaces or wrapping them with proxies.(spring提供的工廠鉤子,用於修改實例對象,可以生成代理對象,是AOP的底層 )
  • 模擬:
A a = new A();
a = B.before(a);//將a的實例對象傳遞給後處理bean,可以生成代理對象並返回
a.init();//此時a已經是代理對象
a = B.after(a);
----開啓事務----
a.method();//生成代理對象,目的是:在目標方法執行前後執行(例如開啓事務、提交事務)
----提交事務----
a.destory();

 

  • 配置信息 
<bean class=""></bean>

 

  • 測試 
  • BeanPostProcessor實現類:此時返回值爲null,則會出現空指針異常
public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自動生成的方法存根
		System.out.println("before method");
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自動生成的方法存根
		System.out.println("after method");
		return bean;
	}	
}
  • 配置文件:(5.4.1配置文件的基礎上,將後處理的實現類註冊給spring)
<?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 definitions here 
    init-method:用於配置初始化方法:準備數據
    destroy-method:用於配置銷燬方法:清理資源等
    -->
	<bean id = "People" class = "test_e_lifecycle.PeopleImpl" init-method = "myInit" destroy-method = "myDestroy"></bean>
	<!-- 將後處理的實現類註冊給spring-->
	<bean class = "test_e_lifecycle.MyBeanPostProcessor"></bean>
</beans>
  •  測試結果:在執行before()方法後,實例對象變爲空,出現java.lang.NullPointerException

BeanPostProcessor的實現類中的方法添加返回值:

public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自動生成的方法存根
		System.out.println("before method" + " , " + beanName);
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自動生成的方法存根
		System.out.println("after method" + " , " + beanName);
		return bean;
	}	
}
  • 結果如下:此時就會按照:before()、init()、after()、實現類的方法、destroy()的順序進行執行

  • 繼續實現在執行目標方法前後進行開啓事務和提交事務,修改BeanPostProcessor的實現類
public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自動生成的方法存根
		System.out.println("before method" + " , " + beanName);
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自動生成的方法存根
		System.out.println("after method" + " , " + 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 {
						// TODO 自動生成的方法存根
						System.out.println("-----開啓事事務-----");
						//執行目標方法
						Object obj = method.invoke(bean, args);
						System.out.println("-----提交事務-----");
						return obj;
					}});
	}	 
}
  • 結果:

  •  總結:兩個步驟
  1. BeanPostProcessor的實現類 (涉及到動態代理)
  2. 配置  <bean class=“BeanPostProcessor的實現類”></bean>

5、屬性依賴注入

5.5.1、構造方法(之後再補充)

5.5.2、setter方法

  • 普通類型屬性的配置文件
<bean id = "" class = "實現類的權限定名">
    <!-- 第一種方式 (推薦)-->
    <property name = "屬性名" value = "值"></property>
    <!-- 第二種方式 (不推薦)-->
    <property name = "屬性名">
        <value>"值"</value>
    </property>
</bean>

 

  • 引用類型屬性的配置文件
<bean id = "" class = "實現類權限定名">
    <!-- 第一種方法 (推薦)-->
    <property name = "屬性名" ref = "另一個bean的id"></property>
    <!-- 第二種方法 (不推薦)-->
    <property name = "屬性名">
        <ref bean = "另一個bean的id"/>
    </property>
</bean>

 

  • 測試

 準備的兩個類:

public class People {
	private String pName;
	private Integer age;
	private Address homeAddr;//家庭地址
	private Address companyAddr;//公司地址
	public String getpName() {
		return pName;
	}
	public void setpName(String pName) {
		this.pName = pName;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public Address getHomeAddr() {
		return homeAddr;
	}
	public void setHomeAddr(Address homeAddr) {
		this.homeAddr = homeAddr;
	}
	public Address getCompanyAddr() {
		return companyAddr;
	}
	public void setCompanyAddr(Address companyAddr) {
		this.companyAddr = companyAddr;
	}
	@Override
	public String toString() {
		return "People [pName=" + pName + ", age=" + age + ", homeAddr=" + homeAddr + ", companyAddr=" + companyAddr+ "]";
	}
}

/********************************************************************************/
public class Address {
	private String addr;//地址信息
	private String tel;//地址的詳細電話
	//添加setter方法
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	public String getAddr() {
		return addr;
	}
	public String getTel() {
		return tel;
	}
	@Override
	public String toString() {
		return "Address [addr=" + addr + ", tel=" + tel + "]";
	}	
}

編寫配置文件

<?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 = "People" class = "test_f_xml_b_setter.People">
		<property name="pName" value = "jack"></property>
		<property name="age">
			<value>20</value>
		</property>
		<property name="homeAddr" ref = "homeAddr"></property>
		<property name = "companyAddr">
			<ref bean = "companyAddr"/>
		</property>
	</bean> 
	<!-- Address -->
	<bean id="homeAddr" class = "test_f_xml_b_setter.Address">
		<property name = "addr" value = "東風大道"></property>
		<property name = "tel" value = "88888888"></property>
	</bean>
	
	<bean id="companyAddr" class = "test_f_xml_b_setter.Address">
		<property name ="addr" value = "發展大道"></property>
		<property name ="tel" value = "66666666"></property>
	</bean>
</beans>

測試類

public class TestSetter {
	@Test
	public void demo01() {
		String xmlPath = "test_f_xml_b_setter/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = (People) applicationContext.getBean("People");
		String str = people.toString();
		System.out.println(str);
	}
}

測試結果:

5.5.3、P命令空間[瞭解]

  • 作用:對“setter方法”注入進行簡化,替換<property>,替換如下
<bean id = "" class = "實現類的權限定名" p:屬性名 = "普通值" p:屬性名-ref = "引用值">

 

  •  p命名空間使用的前提,必須添加命名空間

  • 測試

修改配置文件如下:

<?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:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<bean id = "homeAddr" class = "test_f_xml_c_p.Address" 
	p:addr="東風大道" 
	p:tel="88888888">
	</bean>
	<bean id = "companyAddr" class = "test_f_xml_c_p.Address" 
	p:addr="發展大道" 
	p:tel="66666666">
	</bean>
	
	<bean id = "People" class = "test_f_xml_c_p.People" 
	p:pName = "jack" 
	p:age = "20" 
	p:homeAddr-ref="homeAddr" 
	p:companyAddr-ref = "companyAddr">
	</bean>
	
</beans>

測試結果與5.5.3相同

5.5.4、SpEL(瞭解)

  • 對<property>進行統一編程,所有的內容都使用value
<property name="" value="#(表達式)"></property>
數字:#{123}
字符串:#{'jack'}
另外一個bean的引用:#{beanId}
操作數據:#{beanId.propName}
執行方法:#{beadId.toString()}
靜態方法或字段:#{T(類的權限定名).字段|方法}

 

  • 測試
public class Customer {
    private String cname;
    private Integer age;
    private Double pi;//Math.pi
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Double getPi() {
        return pi;
    }
    public void setPi(Double pi) {
        this.pi = pi;
    }
    @Override
    public String toString() {
        return "Customer [cname=" + cname + ", age=" + age + ", pi=" + pi + "]";
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

配置文件

<?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 = "customer" class = "test_f_xml_d_spel.Customer">
    	<property name = "cname" value = "#{'jack'}"></property>
    	<property name = "age" value = "#{24}"></property>
    	<property name ="pi" value = "#{T(java.lang.Math).PI}"></property>
    </bean>
</beans>

測試類:

public class TestSpel {
	@Test
	public void demo01() {
		String xmlPath = "test_f_xml_d_spel/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		Customer customer = applicationContext.getBean("customer",Customer.class);
		System.out.println(customer.toString());
	}

}

測試結果

6、集合注入(Array、List、Set、Map、Properties)

  • 集合的注入都是給<property>添加子標籤
  • 一般情況下普通數據是<value>,引用數據是<ref>
  • 數組:<array>
  • List:<list>
  • Set:<set>
  • Map:<map>
  • Properties:<props>

測試

public class CollectionData {
	private String[] arrayData;
	private List<String> listData;
	private Set<String> setData;
	private Map<String,String> mapData;
	private Properties propsData;
	public String[] getArrayData() {
		return arrayData;
	}
	public void setArrayData(String[] arrayData) {
		this.arrayData = arrayData;
	}
	public List<String> getListData() {
		return listData;
	}
	public void setListData(List<String> listData) {
		this.listData = listData;
	}
	public Set<String> getSetData() {
		return setData;
	}
	public void setSetData(Set<String> setData) {
		this.setData = setData;
	}
	public Map<String, String> getMapData() {
		return mapData;
	}
	public void setMapData(Map<String, String> mapData) {
		this.mapData = mapData;
	}
	public Properties getPropsData() {
		return propsData;
	}
	public void setPropsData(Properties propsData) {
		this.propsData = propsData;
	}
	@Override
	public String toString() {
		return "CollectionData [\narrayData=" + Arrays.toString(arrayData) + ", \nlistData=" + listData + ", \nsetData="
				+ setData + ", \nmapData=" + mapData + ", \npropsData=" + propsData + "\n]";
	}
}

配置文件:

<?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 = "collectionData" class = "test_f_xml_e_collection.CollectionData">
   		<property name = "arrayData">
   			<array>
   				<value>array-String1</value>
   				<value>array-String2</value>
   				<value>array-String3</value>
   				<value>array-String4</value>
   			</array>
   		</property>
   		<property name = "listData">
   			<list>
   				<value>list-String1</value>
   				<value>list-String2</value>
   				<value>list-String3</value>
   				<value>list-String4</value>
   			</list> 
   		</property>
   		<property name = "SetData">
   			<set>
   				<value>set-String1</value>
   				<value>set-String2</value>
   				<value>set-String3</value>
   			</set>
   		</property>
   		<property name="mapData">
   			<map>
   				<entry key="key1" value="map-String1"></entry>
   				<entry key="key2" value="map-String2"></entry>
   				<entry key="key3" value="map-String3"></entry>
   				<entry>
   					<key><value>key4</value></key>
   					<value>map-String4</value>
   				</entry>
   			</map>
   		</property>
   		<property name="propsData">
   			<props>
   				<prop key="key1">props-String1</prop>
   				<prop key="key2">props-String2</prop>
   				<prop key="key3">props-String3</prop>
   			</props>
   		</property>
   	</bean>
</beans>

測試類:

public class TestCollection {
	@Test
	public void demo() {
		String xmlPath = "test_f_xml_e_collection/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		CollectionData collectionData = applicationContext.getBean("collectionData",CollectionData.class);
		System.out.println(collectionData.toString());
	}

}

測試結果:

6、裝配Bean基於註解

6.1、什麼是註解

  • 註解:就是一個類,使用@註解名稱
  • 開發中:使用註解取代xml文件
  • 使用的前提:添加命名空間,讓spring掃描含有註解的類
  • 在參考文件中找到:the context schema

  •  schema的命名空間

1、命名空間聲明:

          默認:xmlns=”“   <標籤名>-->  <bean>

          顯示:xmlns別名=”“    <別名標籤名>--><context:...>

2、確定schema xsd文件位置

          xsl:schemaLocation=”名稱1   位置1   名稱2   位置2....“(內容都是成對的,【名稱 位置】)

6.2、註解分類

1、@Component 取代 <bean class = “”>

      @Component("id) 取代 <bean id = "" class = "">

測試:

//定義一個接口
public interface People {
	public void newPeople();
}
//接口的實現類
@Component("people")
public class PeopleImpl implements People {
	@Override
	public void newPeople() {
		// TODO 自動生成的方法存根
		System.out.println("create a people");
	}
}
//測試類
public class TestDemo {
	@Test
	public void demo() {
		String xmlPath = "test_g_annotation_a_ioc/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("people",People.class);
		people.newPeople();
	}
}

配置文件:

<?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:context="http://www.springframework.org/schema/context" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context.xsd"> 
    <!-- 組件掃描,掃描含有註解的類-->
    <context:component-scan base-package="test_g_annotation_a_ioc"></context:component-scan>   
</beans>

2、web開發,提供3個@Component註解衍生註解(功能一樣),取代<bean class="">

      @Repository:dao層

      @Service:service層

      @Controller:web層

3、依賴注入    給私有字段設置,也可以給setter方法設置

      普通值:@value("")

      引用值:

               方式一:按照【類型】注入    

                     @Autowired

               方式二:按照【名稱】注入1

                     @Autowired

                     @Qualifier("名稱")

               方式三:按照【名稱】注入2

                     @Resource("名稱")

測試:

@Controller("studentActionId")
public class StudentAction {
	@Autowired//默認  按照類型注入
	private StudentService studentService;
	public void execute() {
		studentService.addStudent();
	}
}
//service
public interface StudentService {
	public void addStudent();
}
//StudentService的實現類
@Service
public class StudentServiceImpl implements StudentService {
	private StudentDao studentDao;
	@Autowired//默認  按照類型注入
	@Qualifier("studentDaoId")
	public void setStudentDao(StudentDao studentDao) {
		this.studentDao = studentDao;
	}
	@Override
	public void addStudent() {
		// TODO 自動生成的方法存根
		//System.out.println("service");
		studentDao.addStudent();
	}
}
//dao
public interface StudentDao {
	public void addStudent();
}
//StudentDao的實現類
@Repository("studentDaoId")
public class StudentDaoImpl implements StudentDao {
	@Override
	public void addStudent() {
		// TODO 自動生成的方法存根
		System.out.println("create a student");
	}
}

測試類:

public class TestDemo {
	@Test
	public void demo() {
		ApplicationContext applicationContext = new 
				ClassPathXmlApplicationContext("test_g_annotation_b_web/applicationContext.xml");
		StudentAction studentAction = (StudentAction) applicationContext.getBean("studentActionId");
		studentAction.execute();
	}
}

配置文件

<?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:context="http://www.springframework.org/schema/context" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context.xsd"> 
    <context:component-scan base-package="test_g_annotation_b_web"></context:component-scan>
</beans>

 

6.3、生命週期

     初始化:@PostConstruct

     銷燬:@PreDestory

6.4、作用域

     @Scope("prototype") 多例

7、註解和xml混合使用

1、將所有的bean都配置在xml中 <bean id = “” class = “”>

2、將所有的依賴都使用註解  @Autowired

      默認不生效,爲了生效,需要在xml文件中配置:<context annotation-config></context annotation-config>

總結:註解1 :<context-component-scan base-package ="">

           註解2 :<context annotation-config>

1、一般兩個註解不一起使用

1、"註解1"掃描含有註解(@Component等)類的,注入的註解自動的生效,"註解2"只在xml和註解(注入)混合使用時,使注入註解生效

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章