1. Spring的出現是爲了取代EJB(Enterprise JavaBean)的臃腫、低效、脫離現實的缺點。Spring致力於J2EE應用的各層(表現層、業務層、持久層)的解決方案,Spring是企業應用開發的「一站式」選擇。java
2. 定義:Spring是分層的JavaSE/EE應用一站式的輕量級開源框架(官網: http://spring.io/ ),以Ioc(Inverse of control)控制反轉和Aop(Aspect Oriented Programming)面向切面編程爲核心。web
3. 優勢:spring
4. spring核心 :Ioc(控制反轉)和aop(面向切面編程)。重點是:IOC,spring要管理各各層的bean。編程
5. Spring模塊組件圖:數組
1. 不使用ioc,代碼中建立一個對象直接操做接口實現類,並無面向接口開發。面向接口開發指的是調用接口的方法,只面向接口而不面向接口實現類,由於一個接口可能有多個實現類。而沒有面向接口開發的問題就是調用接口的類和接口實現類之間存在直接耦合。好比下列代碼spring-mvc
//老闆向一個寫字員發出命令去作一個工做 public class Boss { private Writer emp;//直接使用Writer類,與Boss產生強依賴關係,直接耦合 //老闆只能向寫字員發出命令,若是想要向一個祕書或其餘員工發出命令則沒法實現,這顯然是不合理的 public void order(){ emp=new Writer(); emp.doJob(); } } public class Writer{ public void doJob(){ System.out.println("do something"); } }
面向接口開發的改進代碼:session
//老闆向一個員工發出命令去作一個工做 public class Boss { private Employee emp;//使用Employee接口,將具體實現類與Boss解耦合,這樣就大大加強了代碼的可重用性並減弱耦合度 //老闆能夠向任何一個實現了Employee接口的員工類發出命令 public void order(){ emp=new Writer(); emp.doJob(); } } public class Writer implements Employee{ public void doJob(){ System.out.println("do something"); } } public interface Employee { public void doJob(); }
2. IOC:Inverse of Control,即控制反轉。是指將原來程序中本身建立實現類對象的控制權反轉到IOC容器中。只須要經過IOC獲了對象的實例,將IOC當成一個黑盒子、工廠。對象只與工廠耦合,對象之間沒有耦合。而上面的代碼也能夠改成mvc
//老闆向一個員工發出命令去作一個工做 public class Boss { private Employee emp;//使用Employee接口,這樣就大大加強了代碼的可重用性並減弱耦合度 //老闆能夠向任何一個實現了Employee接口的員工類發出命令,但這裏的Employee的具體實現類對象由IOC容器提供,經過IOC容器來生成所須要的對象,這樣能夠將Boss類與具體員工類解耦,全部的類之間的依賴關係都由IOC容器進行管理,便於修改維護 public void order(){ emp=IOC容器.getEmp(); emp.doJob(); } } public class Writer implements Employee{ public void doJob(){ System.out.println("do something"); } } public interface Employee { public void doJob(); }
1. 首先創建一個Maven項目,經過Maven來導入所須要的jar包,主要是spring-webmvc.jar以及其相關的依賴jar包,使用4.3.版本,另外要注意,JDK版本與Spring版本的兼容問題,Spring4.0之後的版本建議使用JDK1.8版本;其次要導入commons-logging.jar,該包是Spring所使用的JCL日誌體系jar包,只有相關接口,具體的實現類還須要導入log4j.jar。app
2. 編寫Spring IOC容器的配置文件:是一個xml文件框架
<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" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
//注意,一個JavaBean類的規範實現 public class UserData{ private String cn_user_id; private String cn_user_name; private String cn_user_password; public static UserData getUser(){ return new UserData("9527","9527","9527"); } public UserData(String cn_user_id, String cn_user_name, String cn_user_password) { super(); this.cn_user_id = cn_user_id; this.cn_user_name = cn_user_name; this.cn_user_password = cn_user_password; } //IOC容器中的bean必須有無參構造方法,也就是默認構造方法 public UserData() { super(); } public String getCn_user_id() { return cn_user_id; } public void setCn_user_id(String cn_user_id) { this.cn_user_id = cn_user_id; } public String getCn_user_name() { return cn_user_name; } public void setCn_user_name(String cn_user_name) { this.cn_user_name = cn_user_name; } public String getCn_user_password() { return cn_user_password; } public void setCn_user_password(String cn_user_password) { this.cn_user_password = cn_user_password; } }
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <!-- bean標籤: 1.id/name屬性:用來標示bean的名稱,該名稱在SpringIOC容器中不容許重複,若是不指定名稱,將默認爲類路徑 2.class屬性:IOC要管理實現類的全限定路徑名,IOC將根據此路徑去實例化類對象 --> <bean id="user" class="com.cloud_note.entity.UserData"></bean> <!-- SpringIOC實例化bean的三種方法: 1.默認無參構造器 2.有參構造器 3.靜態工廠方法 --> <!-- 有參構造器方法 --> <bean id="user1" class="com.cloud_note.entity.UserData"> <!-- index指參數在參數列表的下標,從0開始 --> <constructor-arg index="0" value="9527" type="java.lang.String"></constructor-arg> <constructor-arg index="1" value="9527" type="java.lang.String"></constructor-arg> <constructor-arg index="2" value="9527" type="java.lang.String"></constructor-arg> </bean> <!-- 靜態工廠方法,經過類中的靜態工廠方法生成bean實例 --> <bean id="user2" class="com.cloud_note.entity.UserData" factory-method="getUser"> <!-- bean做用域: 1.singleton:單例模式,即在Spring容器啓動時只生成一個bean實例,在每次訪問(getBean)時都將此對象返回,Spring容器默認此方式 2.prototype:多例模式,即每次訪問(getBean)Spring容器都會返回一個新實例 3.request 4.session --> <bean id="user" class="com.cloud_note.entity.UserData" scope="singleton"></bean> <bean id="user1" class="com.cloud_note.entity.UserData" scope="prototype"></bean> </bean> </beans>
//測試從Spring中獲取bean實例,該測試方法須要導入junit的jar包,來使用@Test相關注解 public class TestCase1 { //測試無參構造器方法 @Test public void test1(){ //1.獲取SpringIOC容器對象 ApplicationContext app=new ClassPathXmlApplicationContext("config/applicationContext.xml"); //2.從SpringIOC中獲取對應的bean實例 UserData user=(UserData) app.getBean("user"); System.out.println("獲取成功"); } //測試有參構造器方法 @Test public void test2(){ ApplicationContext app=new ClassPathXmlApplicationContext("config/applicationContext.xml"); UserData user=(UserData) app.getBean("user1"); System.out.println(user.getCn_user_id()); } //測試靜態工廠方法 @Test public void test3(){ ApplicationContext app=new ClassPathXmlApplicationContext("config/applicationContext.xml"); UserData user=(UserData) app.getBean("user2"); System.out.println(user.getCn_user_id()); } //獲取SpringIOC容器對象的方法 @Test public void test4(){ //1.FileSystemXmlApplicationContext是經過加載文件系統路徑下的配置文件來建立一個容器實例 ApplicationContext app1=new FileSystemXmlApplicationContext("/src/main/resources/config/applicationContext.xml"); //2.ClassPathXmlApplicationContext是經過加載classpath路徑下的配置文件來建立一個容器實例 ApplicationContext app2=new ClassPathXmlApplicationContext("config/applicationContext.xml"); //3.同時加載多個配置文件,能夠連續填寫多個路徑參數或傳入數組,或者經過通配符來加載 ApplicationContext app3=new ClassPathXmlApplicationContext("config/applicationContext.xml","config/applicationContext1.xml"); String[] configs=new String[]{"config/applicationContext.xml","config/applicationContext1.xml"}; ApplicationContext app4=new ClassPathXmlApplicationContext(configs); ApplicationContext app5=new ClassPathXmlApplicationContext("classpath:config/applicationContext*.xml"); }
3. 使用註解向IOC容器中添加bean:
<?xml version="1.0" encoding="UTF-8"?> <!--省略xml約束--> <beans> <!-- Spring註解開發:經過註解來管理Spring的bean --> <!-- 開啓組件掃描,用以掃描指定包內帶有實例化註解的類 --> <context:component-scan base-package="package"></context:component-scan> </beans>
1. 即IOC容器在運行期間動態的將對象的依賴關係注入到對象的屬性中,底層原理爲:首先生成類對象,依據所依賴的屬性類型生成屬性實例,而後經過set方法來實現注入,或經過有參構造器在生成類的實例時注入所依賴的屬性實例
2. 依賴注入的實現方式有兩種:有參構造器實現注入、set方法實現注入
3. 經過配置文件配置依賴注入:有參構造器在上面的IOC介紹中已經演示
<?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" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd"> <!--set方法實現注入--> <bean id="user" class="UserData"></bean> <bean id="book" class="Book"> <!-- property標籤:指定注入的屬性 name屬性用來指定類中須要注入的屬性名,由set方法後的字符串首字母小寫決定,即調用注入的set方法時將由set+name屬性值 來決定調用那個set方法 ref屬性表示被注入的bean的id value屬性表示一個具體的值,用於java中的簡單類型 --> <property name="user" ref="user"></property> </bean> <!-- set方法能夠注入的屬性類型 --> <bean id="queryVo" class="QueryVo"> <!-- 基本類型 --> <property name="t1" value="vn"></property> <property name="t2" value="1"></property> <!-- pojo類型 --> <property name="t3" ref="user"></property> <!-- List類型 List<String> --> <property name="t4"> <list> <value>vn</value> </list> </property> <!-- List類型 List<UserData> --> <property name="t5"> <list> <ref bean="user"/> </list> </property> <!-- Map類型 --> <property name="t6"> <map> <entry key="1" value="vn"></entry> </map> </property> <!-- Properties類型 --> <property name="t7"> <props> <prop key="name">vn</prop> </props> </property> </bean> </beans>
4. 經過註解進行依賴注入:
@Component("book") @Scope("prototype") public class Book implements Serializable { private String cn_notebook_id; //@Autowired //@Qualifier("user") @Resource(name="user") private UserData user; public UserData getUser() { return user; } //@Autowired //@Qualifier("user") public void setUser(UserData user) { this.user = user; } public String getCn_notebook_id() { return cn_notebook_id; } public void setCn_notebook_id(String cn_notebook_id) { this.cn_notebook_id = cn_notebook_id; } }