Spring的IOC的註解開發(案例+解析)

一、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上設置注入的屬性
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章