爲什麼要使用Spring,優點是什麼?
1.高內聚低耦合,簡化開發
spring是一個大工廠(容器),可以將對象的創建和依賴關係的維護全部交給spring管理。
2.支持Aop編程
方便對程序的權限攔截和運行性能進行監控
3.聲明式事務支持
通過過配置就可以完成對事務的管理,無需手動編程
4.支持Junit
5.方便集成各種優秀的框架
核心技術
IOC:控制反轉
什麼是控制反轉?Ioc不是一種技術而是一種設計思想,傳統的開發中我們在對象的內部通過new直接創建對象,是程序主動創建依賴對象。IOC意味着我們將對象的控制權交給專門容器去管理。這樣就降低了程序的耦合性。控制是什麼?主要就是控制了外部資源獲取。反轉:傳統的方式是我們在自己在對象中主動控制直接獲取依賴對象,就是正轉。而反轉則是由容器來幫助我們創建對象和注入依賴對象。對象只是被動的接受依賴對象。也就是說依賴對象的獲取被反轉了。
簡單的說就是A類要使用B接口中的方法 我們傳統的做法就是在A類中直接new一個B接口的實現類對象。但是顯然這樣做類和接口的依賴太強了。IOC是將A類B接口和他的實現類交給IOC容器,通過IOC容器的配置來實現他們之間的關聯。
DI:依賴注入
DI是什麼?IOC和DI是同一概念的不同描述。
DI的三種方式:
測試類
package com.spring.demo;
public class BookServiceImpl implements BookService {
@Override
public void insert() {
System.out.println("調用dao");
}
}
package com.spring.demo;
public class BookDaoImpl implements BookDao {
@Override
public void insert() {
System.out.println("插入數據");
}
}
- 構造器注入
package com.spring.demo;
public class BookServiceImpl implements BookService {
//傳統方式 BookDao b=new BookDaoImpl();
private BookDao bookdao;
//構造函數
public BookServiceImpl(BookDao bookdao) {
this.bookdao = bookdao;
}
@Override
public void insert() {
System.out.println("調用dao");
bookdao.insert();
}
}
<?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="Dao" class="com.spring.demo.BookDaoImpl"></bean>
<bean id="Service" class="com.spring.demo.BookServiceImpl">
<!-- 構造默認從零開始 -->
<constructor-arg index="0" ref="Dao">
</constructor-arg>
</bean>
</beans>
- set方法注入(屬性注入)
public class BookServiceImpl implements BookService {
// 之前的方式 BookDao dao=new BookDaoImpl(); 耦合性強
private BookDao bookDao;
// set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
@Override
public void insert() {
System.out.println("調用dao");
this.bookDao.insert();
}
}
BooKDao省略
<?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 -->
<!-- Ioc 控制反轉 ,創建service實例 -->
<bean id="BookService" class="BookServiceImpl">
<!-- service依賴於Dao 注入 name bean的屬性名 ref 注入的bean的id -->
<property name="bookDao" ref="BookDao"></property>
</bean>
<!-- Ioc 創建BookDao實例 -->
<bean id="BookDao" class="BookDaoImpl"></bean>
</beans>
注意的是:假如我們要注入一個簡單javaBean對象,他沒有無參的構造方法是無法使用屬性注入的
package com.spring.demo;
public class User {
private String name;
private Integer age;
public User(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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
">
<!-- type參數返回值類型 index 參數位置 -->
<bean id="user" class="com.spring.demo.User">
<constructor-arg type="java.lang.String" index="0"
value="花花"></constructor-arg>
<constructor-arg type="java.lang.Integer" index="1"
value="10"></constructor-arg>
</bean>
<bean id="Dao" class="com.spring.demo.BookDaoImpl"></bean>
<bean id="Service" class="com.spring.demo.BookServiceImpl">
<property name="user" ref="user"></property>
<!-- 構造默認從零開始 -->
<constructor-arg ref="Dao">
</constructor-arg>
</bean>
</beans>
所以我們在開發中要保留默認構造,使用屬性注入使用< proprety>標籤 使用構造注入使用的是< constructor-arg>標籤
接口注入(基本不用)
反射獲取實例化對象
註解注入
使用註解注入首先要引入標籤和命名空間。
@Component取代了標籤
@Component取代了
web開發提供了三個衍生註解
@Repository dao層
@Service service 層
@Contorller web層
普通值 @Value()
引用值 :
按照類型注入
@Autowired
按照名稱注入
1 .@Autowired
@Qualifier(“名稱”)
2.@Resource(“名稱”)生命週期:
初始化:@PostConstruct
銷燬: @PreDestory
作用域:@Scope(“prototype”)
<?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"> <!-- bean definitions here -->
<!-- 掃描組件 -->
<context:component-scan base-package="com.spring.annotation"></context:component-scan>
</beans>
package com.spring.annotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller("BookActionid")
public class BookAction {
//按類型注入
@Autowired
private BookService bookService;
public void insert() {
System.out.println("這是web");
bookService.insert();
}
}
package com.spring.annotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl implements BookService {
private BookDao bookdao;
//按名稱注入
@Autowired
@Qualifier("BookDaoImpl")
public void setBookdao(BookDao bookdao) {
this.bookdao = bookdao;
}
@Override
public void insert() {
System.out.println("調用dao");
bookdao.insert();
}
}
package com.spring.annotation;
import org.springframework.stereotype.Repository;
@Repository("BookDaoImpl")
public class BookDaoImpl implements BookDao {
@Override
public void insert() {
System.out.println("插入數據");
}
}
- 靜態工廠注入
常用於整合其他框架 ,靜態工廠所有方法必須是static的
package com.spring.staticFactory;
public class BookServiceImpl implements BookService {
@Override
public void insert() {
System.out.println("靜態工廠實例化");
}
}
package com.spring.staticFactory;
public class MyBeanFactory {
public static BookService getServiceInstance() {
return new BookServiceImpl();
}
}
<!-- facory-method 靜態方法名稱 -->
<bean id="BookService" class="com.spring.staticFactory.MyBeanFactory"
factory-method="getServiceInstance"></bean
- 實例工廠注入
實例工廠所有的方法都是非靜態的
package com.spring.InstanFactory;
public class MyBeanFactory {
public BookService getServiceInstance() {
return new BookServiceImpl();
}
}
<!-- 創建工廠實例 factory-bean 確定工廠實例 factory-method 確定普通方法 -->
<bean id="MyBeanFactory" class="com.spring.InstanFactory.MyBeanFactory"></bean>
<bean id="BookService" factory-bean="MyBeanFactory"
factory-method="getServiceInstance"></bean>