1. Spring IOC
1.1 概述
- 把實體的創建權交給Spring,以便解耦,Spring使用配置文件+實例工廠+反射創建實例
1.2 配置文件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">
<!-- id:實例的名稱,可以被配置文件和Spring創建實例時引用 -->
<!-- class:被實例化的類完整路徑 -->
<!-- scope:實例的作用範圍
singleton:單例,該類只會創建一次對象,默認值(常用)
prototype:多例,每次從容器中獲取Bean時,都會創建一個新的實例,Acition實例化需要多例(常用)
request:用於Web應用環境,針對每次HTTP請求都會創建一個實例
session:用於Web應用環境,同一個會話共享同一個實例,不同的會話使用不同的實例
global session:僅在Portlet的Web應用中使用,同一個全局會話共享一個實例,對於非Portlet環境,等同於session
-->
<bean id="student" class="com.domain.Student" scope="singleton"></bean>
<!-- 在一個配置文件中引入多個配置文件(配置文件拆分) -->
<import resource="/applicationContext2.xml"/>
</beans>
1.3 從Spring容器中獲取實例
//讀取spring配置文件
ApplicationContext ac=new ClassPathXmlApplicationContext("/applicationContext.xml");
//根據bean標籤的id屬性值查找實例
Student student= ac.getBean("student",Student.class);
//操作實例對象
System.out.println(student.toString());
2. 依賴注入
2.1 構造方法注入屬性值
<bean id="student" class="com.domain.Student">
<!-- Student類中定義了構造方法Student(Integer id, String name) -->
<!-- constructor-arg表示構造方法的參數,name表示參數名稱,value表示參數值 -->
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="張三"></constructor-arg>
</bean>
2.2 setter方法注入屬性值
<bean id="grade" class="com.domain.Grade">
<!-- property標籤表示一個屬性,name表示屬性名,value表示要注入的屬性值 -->
<property name="id" value="1"></property>
<property name="name" value="高一(1)班"></property>
</bean>
<bean id="student" class="com.domain.Student">
<!-- ref可以注入對象類型的數據,ref的值對應上面id爲grade的bean -->
<property name="grade" ref="grade"></property>
</bean>
2.3 p命名空間注入屬性值
- Spring2.5後才能使用p命名空間
- 需要在beans標籤下引入p命名空間規範
xmlns:p="http://www.springframework.org/schema/p"
<!-- 直接在bean標籤的屬性中使用p命名空間爲對的屬性賦值 -->
<!-- 基本類型格式:【p:對象屬性名="值"】 -->
<!-- 對象引用格式:【P:對象屬性名-ref="值"】 -->
<bean id="grade" class="com.domain.Grade" p:id="2" p:name="高一(4)班"></bean>
<bean id="student" class="com.domain.Student" p:grade-ref="grade"></bean>
2.4 SpEL注入屬性值
- Spring3後才能使用SpEL
- SpEL能執行java代碼(跟EL表達式類似)
<bean id="grade" class="com.domain.Grade">
<!-- SpEL表達式格式: #{值} 值爲字符串需要加單引號 -->
<property name="id" value="#{3}"></property>
<property name="name" value="#{'高三(3)班'}"></property>
</bean>
<bean id="student" class="com.domain.Student">
<!-- 無論值是否爲對象類型,直接用value即可,SpEL會自動解析值類型 -->
<property name="grade" value="#{grade}"></property>
<!-- SpEL可以執行java代碼 -->
<property name="name" value="#{grade.getName()+'的學生'}"></property>
</bean>
2.5 自動裝配autowire
- 2.5.1 自動裝配autowire屬性值
-
byName
- 根據屬性名自動裝配,
- BeanFactory查找id與屬性的setter方法匹配的Bean,找到即自動注入,否則什麼都不做
-
byType 根據屬性類型自動裝配
- 如果正好有一個與依賴屬性類型相同的Bean,就自動裝配這個屬性
- 如果有多個這樣的的Bean,Spring無法決定哪個Bean,就拋出一個致命異常
- 如果沒有匹配的Bean,就什麼都不做,屬性不會被設置
-
no
- 不使用自動裝配
-
constructor
- 跟byType差不多,它是應用於構造注入自動裝配
- 如果在容器中沒有找到與構造器參數類型一致的Bean,那麼將會拋出異常
-
<bean id="userDao" class="com.dao.impl.UserDaoImpl" ></bean>
<bean id="productDao" class="com.dao.impl.ProductDaoImpl"></bean>
<!-- ShoppingCarServiceImpl中需要用到userDao和productDao,autowire能自動給這兩個屬性值(需要setter方法)自動裝配賦值 -->
<bean id="shoppingCarService" class="com.service.impl.ShoppingCarServiceImpl" autowire="byName"></bean>
- 全局自動裝配
- Spring配置文件設置了default-autowire後當前文件的bean都會默認自動裝配,如果是拆分多個配置文件,只有設置了default-autowire的配置文件才生效,其他配置文件不生效
<!-- 在Spring配置文件開頭的<beans>文件中添加default-autowire="自動裝配值" -->
<beans default-autowire="byName" >
2.6 注入不同類型的數據(瞭解)
-
注入基本類型(字符串和其他基本類型)
- 看上面例子
-
引用bean實例
- 看上面例子
-
使用內部Bean
<bean id="userBiz" class="com.biz.impl.UserBizImpl">
<property name="userDao">
<!-- 內部bean直接使用class屬性,不用id屬性,不能被其他bean調用 -->
<bean class="com.dao.impl.UserDaoImpl"></bean>
</property>
</bean>
- 注入List集合或數組類型的屬性值
<bean id="user" class="com.entity.User">
<property name="hobbies">
<!-- list標籤注入List集合或數組的多個值 -->
<list>
<value>籃球</value>
<value>足球</value>
<value>乒乓球</value>
</list>
</property>
</bean>
- 注入Set集合的屬性值
<bean id="user" class="com.entity.User">
<property name="hobbies">
<!-- set標籤注入Set集合 -->
<set>
<value>籃球</value>
<value>足球</value>
<value>乒乓球</value>
</set>
</property>
</bean>
- 注入Map集合的屬性值
<bean id="user" class="com.entity.User">
<property name="hobbies">
<!-- map標籤注入Map集合多個鍵值對 -->
<map>
<!-- 一個entry標籤表示一個鍵值對 -->
<entry>
<!-- entry標籤的子key標籤表示Map集合的key,key標籤包含的value表示key值 -->
<key><value>basketball</value></key>
<!-- entry標籤的子value標籤表示Map集合的value -->
<value>籃球</value>
</entry>
<entry>
<key><value>football</value></key>
<value>足球</value>
</entry>
</map>
</property>
</bean>
- 注入Properties類型的屬性值
<bean id="user" class="com.entity.User">
<property name="hobbies">
<!-- props標籤注入Properties集合多個鍵值對 -->
<props>
<!-- 一個prop標籤表示一個鍵值對 -->
<!-- key屬性表示key值 -->
<!-- prop標籤包含的文本是value值 -->
<prop key="backetball">籃球</prop>
<prop key="football">足球</prop>
</props>
</property>
</bean>
- 注入null和空字符串值
<!-- value標籤中間不填東西就是空字符串 -->
<property name="a"><value></value></property>
<!-- null標籤表示null值 -->
<property name="b"><null/></property>
3. 使用註解方式依賴注入
3.1 修改配置文件
- 標籤多了個xmlns:context項,xsi:schemaLocation的值多了2個
- 設置掃描註解類的包
- default-autowire設置和context:component-scan是在同一個配置文件,則會對類的對象屬性進行自動裝配(對象屬性需要要setter方法,不需要在對象屬性上添加註解)
<?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">
<!-- 註解組件掃描,base-package表示要掃描的包,多個包用逗號隔開 -->
<context:component-scan base-package="com.service.impl,com.dao.impl"></context:component-scan>
</beans>
3.2 常用註解
- 3.2.1 註解定義bean
@Repository("bean id")
用於標註Dao的實現類
@Repository("productDao")
public class ProductDaoImpl implements ProductDao {}
@Service("bean id")
用於標註Service實現類
@Service("shoppingCarService")
public class ShoppingCarServiceImpl implements ShoppingCarService {}
@Controller("bean id")
用於標註控制器類@Component("bean id")
用於標註通用bean的類
- 3.2.2 自動裝配註解
- 註解自動裝配不用setter方法,直接在屬性上面添加註解即可
@Autowired
根據類型進行自動裝配@Qualifier("bean id")
與@Autowired結合一起使用就變成根據名字進行自動裝配@Resource(name="bean id")
根據名字進行自動裝配,等同於上面兩個結合
//@Autowired與@Qualifier結合一起就是按名字自動裝配
@Autowired
@Qualifier("userDao")
private UserDao userDao;
//根據名字進行自動裝配
@Resource(name="productDao")
private ProductDao productDao;
- 3.2.3 基本類型數據註解
@Value("我是註解方式的屬性值")
private String message;
- 3.2.4 bean作用域註解
@Scope("作用域")
在類上面註解作用範圍,作用域的值參考2.5