一、Spring的IOC的註解開發:普通屬性
1、創建一個web項目,引入jar
在Spring4的版本註解開發的時候,除了引入基本的開發包以外,還需要引入aop的包。
2、引入Spring的配置文件
(1) 在src下創建applicationContext.xml
(2) 引入約束:使用註解開發需要引入context約束。
約束路徑:
spring-framework-4.2.4.RELEASE-dist\spring-framework-4.2.4.RELEASE\docs\spring-framework-reference\html\xsd-configuration.html
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"
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 -->
</beans>
3、創建接口和實現類
package com.itzheng.spring.demo1;
public interface UserDao {
public void save();
}
package com.itzheng.spring.demo1;
public class UserDaoImpl implements UserDao {
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("DAO保存用戶的方法執行了。。。。");
}
}
(1)傳統方式
@Test
// 傳統測試方法
public void demo1() {
UserDao dao = new UserDaoImpl();
dao.save();
}
(2)Spring的IOC的註解方式
a、開啓Spring的組件掃描
使用IOC的註解開發,需要配置組件掃描 component-scan 組件掃描(哪些包【包路徑】下的類要使用IOC的註解)
<context:component-scan base-package="com.itzheng.spring.demo1"></context:component-scan>
<?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 -->
<!-- Spring的IOC註解的入門 -->
<!-- 使用IOC的註解開發,需要配置組件掃描 component-scan 組件掃描(哪些包【包路徑】下的類要使用IOC的註解) -->
<context:component-scan base-package="com.itzheng.spring.demo1"></context:component-scan>
</beans>
b、在類上添加註解
在要實例化的類上添加註解
用戶DAO實現類,要在要實現的類上添加註解
@Component(value = "userDao")
// 或者將value省略
相當於在xml 當中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>
package com.itzheng.spring.demo1;
import org.springframework.stereotype.Component;
//用戶DAO實現類,要在要實現的類上添加註解
@Component(value = "userDao") // 或者將value省略 相當於在xml 當中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("DAO保存用戶的方法執行了。。。。");
}
}
c、編寫測試類
(UserDao) applicationContext.getBean("userDao");
是通過註解獲取到UserDaoImpl的實例對象,通過然後通過多態調用對應的方法
getBean獲取Spring當中管理的類
@Test
//Spring的IOC的註解方式
public void demo2() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// (UserDao) applicationContext.getBean("userDao"); 獲取到的是UserDaoImpl
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
4、通過註解方式對實現類進行屬性設置
設置屬性和值
package com.itzheng.spring.demo1;
import org.springframework.stereotype.Component;
public class UserDaoImpl implements UserDao {
private String name;
public void setName(String name) {
this.name = name;
}
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("DAOImpl保存用戶的方法執行了。。。。"+name);
}
}
(1)傳統方式設置值
@Test
// 傳統測試方法
public void demo1() {
UserDaoImpl dao = new UserDaoImpl();
dao.setName("張三");
dao.save();
}
(2)Spring的IOC的註解方式設置值設置屬性和值
用戶DAO接口的實現類上添加註解,也就是在Impl的類上添加註解
@Component(value = "userDao")
或者將value省略 @Component( "userDao")
相當於在xml 當中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>
也就是工廠可以通過userDao獲取到對應的UserDaoImpl對象
註解方式:
使用註解方式,在實現類當中是可以沒有set方法的。
兩種情況
a、屬性如果提供set方法就將註解加在set方法上
package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//用戶DAODM實現類,要在要實現的類上添加註解
@Component(value = "userDao") // 或者將value省略 相當於在xml 當中配置<bean id="userDao"
// class="com.itzheng.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
private String name;
@Value("李四")
public void setName(String name) {
this.name = name;
}
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("DAOImpl保存用戶的方法執行了。。。。"+name);
}
}
b、屬性如果不提供set方法就將註解加在屬性上
package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
//用戶DAODM實現類,要在要實現的類上添加註解
@Component(value = "userDao") // 或者將value省略 相當於在xml 當中配置<bean id="userDao" class="com.itzheng.spring.demo1.UserDaoImpl"/>
public class UserDaoImpl implements UserDao {
@Value("李四")
private String name;
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("DAOImpl保存用戶的方法執行了。。。。"+name);
}
}
c、測試以上兩種賦值的效果相同
@Test
//Spring的IOC的註解方式
public void demo2() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// (UserDao) applicationContext.getBean("userDao"); 獲取到的是UserDaoImpl
UserDao userDao = (UserDao) applicationContext.getBean("userDao");
userDao.save();
}
二、Spring的IOC的註解開發:註解詳解+屬性注入
1、@Component:組件
修飾一個類,將這個類交給Spring管理。
這個註解有三個延伸註解(功能類似),用來修飾類的
(1)@Controller:修飾web層的類:
(2)@Service:修飾service層的類:
(3)@Repository:修飾dao層的類:
@Repository是將UserDaoImpl 配置,
工廠可以通過userDao來獲取對應的UserDaoImpl 對象的實例,
其他兩個作用一樣只是修飾的類的層不同
package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
//用戶DAO實現類,要在要實現的類上添加註解
@Repository("userDao")
public class UserDaoImpl implements UserDao {
@Value("李四")
private String name;
/*
* public void setName(String name) { this.name = name; }
*/
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("DAOImpl保存用戶的方法執行了。。。。" + name);
}
}
2、屬性注入的註解
(1)普通屬性
@Value:設置普通屬性的值。
(2)對象類型的屬性:@Autoware:設置對象類型的屬性的值,但是它是按照類型來完成的屬性注入。
package com.itzheng.spring.demo1;
public interface UserDao {
public void save();
}
@Value(“李四”)將屬性注入到UserDaoImpl 的name當中
package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
@Repository("userDao")//
public class UserDaoImpl implements UserDao {
@Value("李四")
private String name;
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("DAOImpl保存用戶的方法執行了。。。。" + name);
}
}
創建UserService
package com.itzheng.spring.demo1;
public interface UserService {
public void save();
}
@Service(“UserService”)
// 相當於配置了<bean id="userService" class="com.itzheng.spring.demo1.UserServiceImpl">
在工廠當中通過UserService獲取到UserServiceImpl對象的實例
在Service當中調用Dao層,通過註解的方式將Dao注入
UserServiceImpl
@Autowired修飾屬性,將屬性對應的類,注入到當前類當中
package com.itzheng.spring.demo1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service("UserService") // 相當於配置了<bean id="userService"
// class="com.itzheng.spring.demo1.UserServiceImpl">
public class UserServiceImpl implements UserService {
// 注入DAO
@Autowired
private UserDao userDao;
//在Service當中調用Dao層
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("UserServiceImpl執行了");
userDao.save();
}
}
測試
@Test
// Spring的IOC的註解方式
public void demo3() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
// (UserDao) applicationContext.getBean("userDao"); 獲取到的是UserDaoImpl
UserService userService = (UserService) applicationContext.getBean("UserService");
userService.save();
}
(3)注意
@Autoware將@Repository修飾的類注入到當前修飾的對象上,
因爲這裏是繼承了UserDao所以,
@Repository修飾的名稱不管是什麼,
在UserServiceImpl當中的@Autoware修飾的userDao,注入的一定是UserDao的對象的實例,也就是userDaoImpl對象
但是在UserDaoImpl上一定要用@Repository來修飾該類
(4)我們的習慣是安裝名稱完成屬性的注入:必須讓@Autowired註解和@Qualifier(value="")一起使用來完成安裝名稱的屬性注入
@Qualifier(value=“userDao”)強制按名稱來完成屬性的注入
@Service("UserService") // 相當於配置了<bean id="userService" class="com.itzheng.spring.demo1.UserServiceImpl">
public class UserServiceImpl implements UserService {
// 注入DAO
@Autowired
@Qualifier(value="userDao")//強制按名稱來完成屬性的注入
private UserDao userDao;
//在Service當中調用Dao層
@Override
public void save() {
// TODO Auto-generated method stub
System.out.println("UserServiceImpl執行了");
userDao.save();
}
}
(5)@Resource:完成對象類型的屬性的注入,按照名稱完成屬性注入。
@Service("UserService") // 相當於配置了<bean id="userService"
// class="com.itzheng.spring.demo1.UserServiceImpl">
public class UserServiceImpl implements UserService {
// 注入DAO
@Resource(name = "userDao")
private UserDao userDao;
// 在Service當中調用Dao層
@Override
public void save() {
System.out.println("UserServiceImpl執行了");
userDao.save();
}
}
註解可以理解爲拆分版的XML和XML的原理相同,所有的註解可以理解爲在同一個XML下的配置
三、Bean的其他的註解
1、生命週期的註解:對類進行初始化的註解(在對應初始化方法上進行註解)
通過設置@Service(“customerService”) 修飾一個類,將這個類交給Spring管理。
@PostConstruct :初始化方法 相當於init-method,在工廠獲得Spring管理的對象,自動執行其對應的初始化方法
@PreDestroy : 銷燬方法 相當於destroy-method=“destroy”,在工廠獲得Spring管理的對象,自動執行其對應的銷燬方法
package com.itzheng.spring.demo2;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.stereotype.Service;
@Service("customerService")//<bean id="" class="" init-method="init" destroy-method="destroy">
public class CustomerService {
@PostConstruct //相當於init-method,在工廠獲得Spring管理的對象,自動執行其對應的初始化方法
public void init() {
System.out.println("CustomerService被初始化了。。。。。");
}
public void save() {
System.out.println("Service的save的方法執行。。。。。");
}
@PreDestroy //相當於destroy-method="destroy",在工廠獲得Spring管理的對象,自動執行其對應的銷燬方法
public void destroy() {
System.out.println("CustomerService被銷燬了。。。。。");
}
}
測試類
package com.itzheng.spring.demo2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo2 {
@Test
public void demo1() {
//通過工廠獲取xml文件
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//getBean獲取Spring當中管理的類
CustomerService customerService = (CustomerService)applicationContext.getBean("customerService");
System.out.println(customerService);
applicationContext.close();//關閉工廠
}
}
2、Bean作用的註解範圍
@Scope:作用範圍
Scope的取值:
singleton:默認單例
prototype:多例
request:
session:
globalsession:
(1)在customerService上設置@Scope註解
在測試類當中創建兩個CustomerService 實例對象
public class SpringDemo2 {
@Test
public void demo1() {
// 通過工廠獲取xml文件
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// getBean獲取Spring當中管理的類
CustomerService customerService1 = (CustomerService) applicationContext.getBean("customerService");
System.out.println(customerService1);
CustomerService customerService2 = (CustomerService) applicationContext.getBean("customerService");
System.out.println(customerService2);
applicationContext.close();// 關閉工廠
}
}
結果證明兩個類是同一個對象,也就是說明Scope的取值默認單例
(2)當@Scope(“singleton”)設置該對象交給Spring的時候是單例創建對象
結果和默認值想效果相同
(3)當@Scope(“prototype”)設置該對象交給Spring的時候是多例創建對象
證明創建的是兩個對象,即爲多例模式
四、IOC的XML和註解開發比較
1、XML和註解的比較
適用場景
XML:可以適用任何場景。
結構清晰,維護方便。
註解:有些地方用不了,(這個類不是自己提供的,原碼當中提的屬性)
純註解(SSH)
開發方便。(編寫類,在類上加註解,將類交給Spring管理,在其他地方通過工廠獲得該類、屬性注入直接在已經交給Spring管理的類當中,通過標籤將屬性注入到對應定義標籤修飾的屬性當中)
五、XML和註解開發的整合
1、XML管理Bean、註解完成屬性注入。(在有掃描器的情況下)
編寫ProductDao 類
package com.itzheng.spring.demo3;
public class ProductDao {
public void save() {
System.out.println("ProductDao的save方法執行了。。。。");
}
}
編寫OrderDao
package com.itzheng.spring.demo3;
public class OrderDao {
public void save() {
System.out.println("OrderDao的save方法執行了。。。。");
}
}
編寫ProductService方法並且設置對應的屬性
package com.itzheng.spring.demo3;
public class ProductService {
private ProductDao productDao;
private OrderDao orderDao;
public void setProductDao(ProductDao productDao) {
this.productDao = productDao;
}
public void setOrderDao(OrderDao orderDao) {
this.orderDao = orderDao;
}
public void save() {
System.out.println("ProductService的save方法執行了。。。。。");
productDao.save();
orderDao.save();
}
}
將三個類交給Spring管理,productDao和orderDao並將注入到productService類當中
<?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 -->
<!-- Spring的IOC註解的入門 -->
<!-- 掃描是爲了掃描類上的註解 -->
<!-- 使用IOC的註解開發,需要配置組件掃描 component-scan 組件掃描(哪些包【包路徑】下的類要使用IOC的註解) -->
<context:component-scan
base-package="com.itzheng.spring"></context:component-scan>
<bean id="productService" class="com.itzheng.spring.demo3.ProductService">
<property name="productDao" ref="productDao"></property>
<property name="orderDao" ref="orderDao"></property>
</bean>
<bean id="productDao" class="com.itzheng.spring.demo3.ProductDao">
</bean>
<bean id="orderDao" class="com.itzheng.spring.demo3.OrderDao">
</bean>
</beans>
編寫測試類
package com.itzheng.spring.demo3;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class SpringDemo3 {
@Test
public void demo1() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
ProductService productService = (ProductService) applicationContext.getBean("productService");
productService.save();
}
}
2、使用XML和註解整合的方式(類的管理通過XML的方式,屬性注入通過註解的方式) 沒有掃描器的情況下(類上沒有註解)
通過註解注入屬性則不需要,提供set方法
並且設置context:annotation會自動根據需要注入的類當中註解,進行屬性的注入
<context:annotation-config></context:annotation-config>
自動將對應類交給Spring,自動將對應的屬性注入到對象當中
<?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 -->
<!-- Spring的IOC註解的入門 -->
<!-- 使用IOC的註解開發,需要配置組件掃描 component-scan 組件掃描(哪些包【包路徑】下的類要使用IOC的註解) -->
<!-- 在沒有掃描的情況下,使用屬性注入的註解 @Resource,@Value,@Autowired,@Qulifier-->
<context:annotation-config></context:annotation-config>
<bean id="productService" class="com.itzheng.spring.demo3.ProductService"></bean>
<bean id="productDao" class="com.itzheng.spring.demo3.ProductDao"> </bean>
<bean id="orderDao" class="com.itzheng.spring.demo3.OrderDao"> </bean>
</beans>
在@Resource上設置注入的屬性