相關代碼地址:https://github.com/weiliangchun/JavaEE/tree/master/SpringHSP
java
spring 中有一個很是重要的概念:bean(是java中的任何一種對象 javabean/service/action/數據源/dao),IOC(控制反轉),DI(依賴注入)git
開發一個spring項目github
<!-- 在容器文件中配置bean(service/dao/domai/action/數據源) --> <!-- bean元素的做用是,當咱們的spring框架加載時候,spring就會自動建立一個bean對象,並放入內存 UserService userService = new UserService(); userService.setName("春春"); --> <bean id="userService" class="com.service.UserService"> <!-- 這裏就體現出注入的概念 --> <property name="name"> <value>春春</value> </property> </bean>
//咱們如今用使用spring來完成上面的任務 //1.獲得spring的applicationContext對象(容器對象) ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService us = (UserService) ac.getBean("userService"); us.sayHello();
spring的運行原理圖
web
咱們再看spring
對上面案例總結:
spring其實是一個容器框架,能夠配置各類bean,而且能夠維護bean與bean的關係,當咱們須要使用某個bean的時候,咱們能夠getBean(id),使用便可.
IOC是什麼?
ioc(inverse of controll ) 控制反轉: 所謂控制反轉就是把建立對象(bean),和維護對象(bean)的關係的權利從程序中轉移到spring的容器(applicationContext.xml),而程序自己再也不維護.
DI是什麼
di(dependency injection) 依賴注入: 實際上di和ioc是同一個概念,spring設計者認爲di更準確表示spring核心技術spring
學框架,最重要的就是學習各個配置數據庫
spring提倡接口編程,配合DI技術能夠達到層與層的解耦數組
如今咱們體驗一下spring的DI配合接口編程,完成一個字母大小寫轉換的案例
思路:緩存
經過上面的案例,咱們能夠初步體會到DI配合接口編程,的確能夠減小層(web層)和業務層的耦合度session
從ApplicationContex 應用上下文容器中獲取bean和從bean工廠容器中獲取bean
結論:
做用域 | 描述 |
---|---|
sigleton | 在每一個Spring IoC容器中一個bean定義對應一個對象實例。 |
prototype | 一個bean定義對應多個對象實例。 |
request | 在一次HTTP請求中,一個bean定義對應一個實例;即每次HTTP請求將會有各自的bean實例,它們依據某個bean定義建立而成。該做用域僅在基於web的Spring ApplicationContext情形下有效。 |
session | 在一個HTTP Session中,一個bean定義對應一個實例。該做用域僅在基於web的Spring ApplicationContext情形下有效。 |
global session | 在一個全局的HTTP Session中,一個bean定義對應一個實例。典型狀況下,僅在使用portlet context的時候有效。該做用域僅在基於web的Spring ApplicationContext情形下有效。 |
入門案例:
//獲取兩個student Student s1=(Student) ac.getBean("student"); Student s2=(Student) ac.getBean("student"); System.out.println(s1+" "+s2);
實際開發中,咱們每每沒用到這麼多的過程,常見的是:
實例化 => IOC注入 => AOP => 使用bean => 關閉bean
做用域 | 描述 |
---|---|
sigleton | 在每一個Spring IoC容器中一個bean定義對應一個對象實例。 |
prototype | 一個bean定義對應多個對象實例。 |
request | 在一次HTTP請求中,一個bean定義對應一個實例;即每次HTTP請求將會有各自的bean實例,它們依據某個bean定義建立而成。該做用域僅在基於web的Spring ApplicationContext情形下有效。 |
session | 在一個HTTP Session中,一個bean定義對應一個實例。該做用域僅在基於web的Spring ApplicationContext情形下有效。 |
global session | 在一個全局的HTTP Session中,一個bean定義對應一個實例。典型狀況下,僅在使用portlet context的時候有效。該做用域僅在基於web的Spring ApplicationContext情形下有效。 |
儘可能使用scope="singleton",不要使用prototype,由於這樣對性能影響較大
點我查看參考代碼文件夾
java中主要的集合有:map set list 數組
list:有序 能夠存儲相同的對象
set:無序 不能夠存儲相同對象 會覆蓋
Department類
package com.hsp.collection; import java.util.List; import java.util.Map; import java.util.Set; public class Department { private String name; private String[] empName; private List<Employee> empList; private Set<Employee> empSets; private Map<String,Employee> empMaps; public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getEmpName() { return empName; } public void setEmpName(String[] empName) { this.empName = empName; } public List<Employee> getEmpList() { return empList; } public void setEmpList(List<Employee> empList) { this.empList = empList; } public Set<Employee> getEmpSets() { return empSets; } public void setEmpSets(Set<Employee> empSets) { this.empSets = empSets; } public Map<String, Employee> getEmpMaps() { return empMaps; } public void setEmpMaps(Map<String, Employee> empMaps) { this.empMaps = empMaps; } }
Employee類
package com.hsp.collection; public class Employee { private String name; private int id; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } }
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="department" class="com.hsp.collection.Department"> <property name="name" value="財務部"/> <!-- 給數組注值 --> <property name="empName"> <list> <value>小明</value> <value>小小明</value> <value>大明</value> </list> </property> <!-- 給List注入值 ,list能夠有相同對象--> <property name="empList"> <list> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> </list> </property> <!-- 給set注入值 ,set不能有相同對象--> <property name="empSets"> <set> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> <ref bean="emp1"/> <ref bean="emp2"/> </set> </property> <!-- 給Map注入值,只要key不同,就能夠裝配value --> <property name="empMaps"> <map> <entry key="1" value-ref="emp1"/> <entry key="2" value-ref="emp2"/> </map> </property> </bean> <bean id="emp1" class="com.hsp.collection.Employee"> <property name="name" value="北京"/> <property name="id" value="1"/> </bean> <bean id="emp2" class="com.hsp.collection.Employee"> <property name="name" value="天津"/> <property name="id" value="2"/> </bean> </beans>
<bean id="foo" class="...Foo"> <property name="屬性"> <!-- 第一種方法引用 --> <ref bean="bean對象名" /> <!-- 第二種內部bean --> <bean> <property name="屬性"> ... </property> </bean> </property> </bean>
public class Student public class Graduate extends Student
在beans.xml中配置
<!-- 配置一個學生對象 --> <bean id="student" class="com.hsp.inherit.Student"> <property name="name" value="小明"/> <property name="age" value="20"/> </bean> <!-- 配置Graduate對象 --> <bean id="graduate" parent="student" class="com.hsp.inherit.Graduate"> <!-- 若是本身配置屬性name,age,則會替換從父對象繼承的數據 --> <property name="name" value="大明"/> <property name="degree" value="學士"/> </bean>
點我查看參考代碼文件夾
beans.xml關鍵代碼
<!-- 配置一個僱員對象 --> <bean id="employee" class="com.hsp.constructor.Employee"> <!-- 經過構造函數來注入屬性值 --> <constructor-arg index="0" type="java.lang.String" value="大明"/> <constructor-arg index="1" type="int" value="23"/> </bean>
set注入的缺點是沒法清晰表達哪些屬性是必須的,哪些是可選的。
構造注入的優點是經過構造強制依賴關係,不可能實例化不徹底的或沒法使用的bean
模式 | 說明 |
---|---|
no | 不使用自動裝配。必須經過ref元素指定依賴,這是默認設置。因爲顯式指定協做者可使配置更靈活、更清晰,所以對於較大的部署配置,推薦採用該設置。並且在某種程度上,它也是系統架構的一種文檔形式。 |
byName | 不使用自動裝配不使用自動裝配。必須經過ref元素指定依賴,這是默認設置。因爲顯式指定協做者可使配置更靈活、更清晰,所以對於較大的部署配置,推薦採用該設置。並且在某種程度上,它也是系統架構的一種文檔形式。 |
byType | 若是容器中存在一個與指定屬性類型相同的bean,那麼將與該屬性自動裝配。若是存在多個該類型的bean,那麼將會拋出異常,並指出不能使用byType方式進行自動裝配。若沒有找到相匹配的bean,則什麼事都不發生,屬性也不會被設置。若是你不但願這樣,那麼能夠經過設置dependency-check="objects"讓Spring拋出異常。 |
constructor | 與byType的方式相似,不一樣之處在於它應用於構造器參數。若是在容器中沒有找到與構造器參數類型一致的bean,那麼將會拋出異常。 |
autodetect | 經過bean類的自省機制(introspection)來決定是使用constructor仍是byType方式進行自動裝配。若是發現默認的構造器,那麼將使用byType方式。 |
<!-- 配置一個master對象 --> <bean id="master" class="com.hsp.autowire.Master" autowire="byName"> <property name="name"> <value>小明</value> </property> </bean> <!-- 配置一個dog對象 --> <bean id="dog" class="com.hsp.autowire.Dog"> <property name="name" value="大黃"/> <property name="age" value="3"/> </bean>
byType
找和屬性類型相同的bean,找不到,裝不上,找到多個拋異常
constructor
查找和bean的構造參數一致的一個或多個bean,若找不到或找到多個,拋異常。按照參數的類型裝配
autodetect
(3)和(2)之間選一個方式。不肯定性的處理與(3)和(2)一致。
defualt
==這個須要在
當你在
若是沒有在
defualt-autorwire=」no」
autowire默認值是default。
default-autowire默認值是no
beans.xml
說明:當經過 context:property-placeholder 引入多個properties文件時,要用逗號隔開
<!-- 引入咱們的db.properties文件 --> <context:property-placeholder location="classpath:com/hsp/dispatch/db.properties,classpath:com/hsp/dispatch/db2.properties"/> <!-- 配置-DBUtil對象 --> <bean id="dbutil1" class="com.hsp.dispatch.DBUtil"> <property name="name" value="${name}" /> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="pwd" value="${pwd}" /> </bean> <!-- 配置-DBUtil對象 --> <bean id="dbutil2" class="com.hsp.dispatch.DBUtil"> <property name="name" value="${db2.name}" /> <property name="driver" value="${db2.driver}" /> <property name="url" value="${db2.url}" /> <property name="pwd" value="${db2.pwd}" /> </bean>
db.properties
name=scott driver=oracle:jdbc:driver:OraclaDriver url=jdbc:oracle:@localhost:3306 pwd=123456
語句1; 語句2; ...
Class Dog { 屬性;->變量 行爲->函數 }
spring的aop中,當你經過代理對象去實現aop的時候,獲取的ProxyFactoryBean是什麼類型?
返回的是一個代理對象,若是目標對象實現了接口,則spring使用jdk 動態代理技術,若是目標對象沒有實現接口,則spring使用CGLIB技術.
資源地址:https://pan.baidu.com/s/1bpGVxgz, 提取密碼 m5fn