Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson 在其著做Expert One-On-One J2EE Development and Design中闡述的部分理念和原型衍生而來。它是爲了解決企業應用開發的複雜性而建立的。Spring使用基本的JavaBean來完成之前只可能由EJB完成的事情。然而,Spring的用途不只限於服務器端的開發。從簡單性、可測試性和鬆耦合的角度而言,任何Java應用均可以從Spring中受益。簡單來講,Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器框架。html
方便解耦,簡化開發java
AOP變成的支持mysql
聲明式事務的支持web
方便程序的測試spring
方便集成各類優秀框架sql
下降JavaEE API的使用難度數據庫
Java源碼是經典學習範例express
Spring框架是一個分層架構,它包含一系列的功能要素並被分爲大約20個模塊。這些模塊分爲Core Container、DataAccess/Integration、Web、AOP、Instrumentation和測試部分。以下圖所示:apache
程序的耦合編程
/** * 客戶的業務層實現類 */ public class CustomerServiceImpl implements ICustomerService { private ICustomerDao customerDao = new CustomerDaoImpl(); }
public class JdbcDemo1 { /** * JDBC操做數據庫的基本入門中存在什麼問題? * 致使驅動註冊兩次是個問題,但不是嚴重的。 * 嚴重的問題:是當前類和mysql的驅動類有很強的依賴關係。 * 當咱們沒有驅動類的時候,連編譯都不讓。 * 那這種依賴關係,就叫作程序的耦合 * * 咱們在開發中,理想的狀態應該是: * 咱們應該盡力達到的:編譯時不依賴,運行時才依賴。 * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { //1.註冊驅動 //DriverManager.registerDriver(new com.mysql.jdbc.Driver()); Class.forName("com.mysql.jdbc.Driver"); //2.獲取鏈接 //3.獲取預處理sql語句對象 //4.獲取結果集 //5.遍歷結果集 }
解決程序耦合的思路
在JDBC種是經過反射來註冊驅動的,代碼以下:
Clas.forName("com.mysql.jdbc.Driver");
工廠模式解耦
控制反轉---Inversion Of Control
上面解耦的思路有兩個問題
以及進行Inversion of Control(IoC) / Dependency Injection(DI)操做相關的全部類。
如郵件服務、任務調度、JNDI定位、EJB集成、遠程訪問、緩存以及各類視圖層框架的封裝等。
準備項目須要得jar包
在src路徑下建立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"> <!-- 約束的位置在: ..\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html 文檔末尾 --> <!-- 1. 基本配置: bean標籤:指定要建立的實體類 id屬性:能夠爲任意值 可是在整個配置文件中惟一 class屬性:要實例化類的全限定名 反射 --> <bean id="user" class="com.itzhouq.domain.User"></bean> </beans>
測試
package com.itzhouq.domain; public class User { public void run() { System.out.println("run"); } }
package com.itzhouq.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.itzhouq.domain.User; public class UserTeset { @Test public void test() {//本身new的對象 User user = new User(); user.run(); } @Test public void test2() {//spring的ioc建立對象 //加載配置文件 src/classes類路徑 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //找Spring要對象 User user = (User) context.getBean("user"); user.run(); } }
做用
屬性
<bean id="user" class="cn.itzhouq.domain.User" scope="singleton" ></bean>
prototype: 多實例
何時用默認值singleton(單實例)? 何時用prototype(多實例)?
單例對象:scope="singleton"
生命週期:
生命週期:
無參構造方式(最經常使用)
@Test//測試bean的三種建立方式------無參構造方式 public void test3() { //加載配置文件 src/classes類路徑 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); //找Spring要對象 User user = (User) context.getBean("user"); user.run(); }
靜態工廠方式(瞭解)
條件:須要有一個工廠類,在這個工廠類中還須要一個靜態方法
package com.itzhouq.utils; import com.itzhouq.domain.User; public class BeanFactory { public static User createUser() { return new User(); } }
<!-- 靜態工廠方式 --> <bean id="user" class="com.itzhouq.utils.BeanFactory" factory-method ="createUser">
測試
@Test//測試bean的三種建立方式------靜態工廠方式 public void test4() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user1 = (User) context.getBean("user"); System.out.println(user1);//com.itzhouq.domain.User@5f3a4b84 User user2 = (User) context.getBean("user"); System.out.println(user2);//com.itzhouq.domain.User@5f3a4b84 }
實例工廠方式(瞭解)
package com.itzhouq.utils; import com.itzhouq.domain.User; public class BeanFactory { // public static User createUser() { // return new User(); // } //普通方法----實例工廠 public User createUser() { return new User(); } }
配置文件
<!-- 實例工廠 --> <bean id="beanFactory" class="com.itzhouq.utils.BeanFactory"></bean> <bean id="user" factory-bean="beanFactory" factory-method="createUser"></bean>
測試
@Test//測試bean的三種建立方式------實例工廠方式 public void test5() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user1 = (User) context.getBean("user"); System.out.println(user1);//com.itzhouq.domain.User@5f3a4b84 User user2 = (User) context.getBean("user"); System.out.println(user2);//com.itzhouq.domain.User@5f3a4b84 }
public class Lession01 { @Test public void test01(){ //Spring容器加載有3種方式 //第一種:ClassPathXmlApplicationContext ClassPath類路徑加載:指的就是classes路徑 //最經常使用,Spring的配置文件之後就放在src路徑下 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //第二種方式:文件系統路徑得到配置文件【絕對路徑】 ApplicationContext context = new FileSystemXmlApplicationContext("E:\\workspaces\\IdeaProject\\Spring-day02-gyf\\src\\beans.xml"); IUserService user = (IUserService) context.getBean("userService"); user.add(); //第三種方式: String path = "E:\\workspaces\\IdeaProject\\Spring-day02-gyf\\src\\beans.xml"; BeanFactory factory = new XmlBeanFactory(new FileSystemResource(path)); IUserService user1 = (IUserService) factory.getBean("userService"); user1.add(); } }
Spring內部建立對象的原理
1. 解析xml文件,得到類名,id,屬性 2. 經過反射,用類型建立對象 3. 給建立的對象賦值
ApplicationContext是對BeanFactory擴展,提供了更多功能
入門舉例:
建立一個接口Car
package com.itzhouq.service; public interface Car { public void run(); }
建立實現類CarImpl
package com.itzhouq.serviceImpl; import com.itzhouq.service.Car; public class CarImpl implements Car { private String name; public void setName(String name) { this.name = name; } @Override public void run() { System.out.println(name+"車跑起來了....."); } }
測試
package com.itzhouq.test; import org.junit.Test; import com.itzhouq.serviceImpl.CarImpl; public class CarTest { @Test//本身new對象 本身屬性賦值的方式 public void test() { CarImpl car = new CarImpl(); car.setName("qq"); car.run();//qq車跑起來了..... } }
入門舉例2:依賴注入的方式
配置文件:
<!-- DI:屬性的依賴注入 --> <bean id="car" class="com.itzhouq.serviceImpl.CarImpl"> <!-- property:是set屬性的方式 name:要賦值的屬性名 value:要賦的值 --> <property name="name" value="蘭博基尼"></property> </bean>
測試
@Test //Spring的IOC public void test2() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); Car car = (Car)context.getBean("car"); //把這個對象的屬性也在建立的時候給順便賦值了-----DI car.run();//蘭博基尼車跑起來了..... }
依賴注入的方式
給CarImpl設置有參構造
package com.itzhouq.serviceImpl; import com.itzhouq.service.Car; public class CarImpl implements Car { private String name; private double price; public void setName(String name) { this.name = name; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getName() { return name; } public CarImpl() {} //有參的構造方法----DI的構造器注入方式 public CarImpl(String name, double price) { super(); this.name = name; this.price = price; } @Override public void run() { System.out.println("價值"+price+"的"+name+"車跑起來了....."); } }
配置文件
<!-- DI的注入方式,構造器注入方式 name:要賦值的屬性名 value:要賦的值(針對的是基本數據類型和String類型) ref針對的是對象類型 --> <bean id="car" class="com.itzhouq.serviceImpl.CarImpl"> <constructor-arg name="name" value="BMW"></constructor-arg> <constructor-arg name="price" value="1000000"></constructor-arg> </bean>
測試
@Test //Spring的DI注入方式----構造器的注入方式(瞭解) public void test3() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); Car car = (Car)context.getBean("car"); car.run();//價值1000000.0的BMW車跑起來了..... }
寫一個Person接口
package com.itzhouq.service; public interface Person { }
PersonImpl實現接口Person,設置set方法
package com.itzhouq.serviceImpl; import com.itzhouq.service.Car; import com.itzhouq.service.Person; public class PersonImpl implements Person { private String name; private Car car; public String getName() { return name; } public void setName(String name) { this.name = name; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "PersonImpl [name=" + name + ", car=" + car + "]"; } }
配置文件
<bean id="car" class="com.itzhouq.serviceImpl.CarImpl"> <constructor-arg name="name" value="BMW"></constructor-arg> <constructor-arg name="price" value="1000000"></constructor-arg> </bean> <!-- DI的注入方式,set注入方式 name:要賦值的屬性名 value:要賦的值(針對的是基本數據類型和String類型) ref針對的是對象類型,指的是Spring中bean的id名 --> <bean id="person" class="com.itzhouq.serviceImpl.PersonImpl"> <property name="name" value="jack"></property> <property name="car" ref="car"></property> </bean>
測試
@Test //Spring的DI注入方式----set的注入方式(瞭解) public void test4() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); Person person = (Person) context.getBean("person"); System.out.println(person); //PersonImpl [name=jack, car=CarImpl [name=BMW, price=1000000.0]] }
配置文件
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" 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="customerService" class="com.itheima.service.impl.CustomerServiceImpl4" p:name="test" p:age="21" p:birthday-ref="now"/> </beans>
建立一個類CollBean,設置set方法
package com.itzhouq.domain; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Properties; public class CollBean { private String[] ss; private List ll; private Map mm; private Properties properties; public String[] getSs() { return ss; } public void setSs(String[] ss) { this.ss = ss; } public List getLl() { return ll; } public void setLl(List ll) { this.ll = ll; } public Map getMm() { return mm; } public void setMm(Map mm) { this.mm = mm; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } @Override public String toString() { return "CollBean [ss=" + Arrays.toString(ss) + ", ll=" + ll + ", mm=" + mm + ", properties=" + properties + "]"; } }
配置文件
<bean id="car" class="com.itzhouq.serviceImpl.CarImpl"> <constructor-arg name="name" value="BMW"></constructor-arg> <constructor-arg name="price" value="1000000"></constructor-arg> </bean> <!-- DI複雜屬性注入 --> <bean id="collBean" class="com.itzhouq.domain.CollBean"> <property name="ss"> <!-- 數組類型 --> <list> <value>aaa</value> <value>bbb</value> <value>ccc</value> </list> </property> <property name="ll"> <!-- 集合類型 --> <list> <value>111</value> <value>222</value> <ref bean="car"></ref> </list> </property> <property name="mm"> <!-- map類型 --> <map> <entry key="k1" value="AAA"></entry> <entry key="k2" value="BBB"></entry> <entry key="k3" value-ref="car"></entry> </map> </property> <property name="properties"> <!-- properties --> <props> <prop key="hibernate.username">root</prop> <prop key="hibernate.password">1234</prop> </props> </property> </bean>
package com.itzhouq.test; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.itzhouq.domain.CollBean; public class CollBeanTest { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml"); CollBean cb = (CollBean) context.getBean("collBean"); System.out.println(cb); /* * CollBean [ss=[aaa, bbb, ccc], * ll=[111, 222, CarImpl [name=BMW, price=1000000.0]], * mm={k1=AAA, k2=BBB, k3=CarImpl [name=BMW, price=1000000.0]}, * properties={hibernate.password=1234, hibernate.username=root}] */ } }
建立dao層和dao實現層
package com.itzhouq.dao; public interface UserDao { void save(); }
package com.itzhouq.daoImpl; import com.itzhouq.dao.UserDao; public class UserDaoImpl implements UserDao{ @Override public void save() { System.out.println("操做數據庫,保存用戶的數據"); } }
建立Service層和實現層
package com.itzhouq.service; public interface UserService { public void save(); }
package com.itzhouq.serviceImpl; import com.itzhouq.dao.UserDao; import com.itzhouq.daoImpl.UserDaoImpl; import com.itzhouq.service.UserService; public class UserServiceImpl implements UserService { private String name; private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } public void setName(String name) { this.name = name; } @Override public void save() { System.out.println(name); //調用dao userDao.save(); } }
配置文件
<?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"> <!-- 建立dao --> <bean id="userDao" class="com.itzhouq.daoImpl.UserDaoImpl"></bean> <!-- 建立service --> <bean id="UserService" class="com.itzhouq.serviceImpl.UserServiceImpl"> <property name="name" value="要開始訪問dao了"></property> <property name="userDao" ref="userDao"></property> </bean> </beans>
測試
@Test //使用Spring的IOC+DI來實現對象的建立和賦值 public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserService userService = (UserService) context.getBean("UserService"); userService.save(); //要開始訪問dao了 //操做數據庫,保存用戶的數據 }