一、Spring 註解版 IOC
1、註解版 IOC 概述
Spring不但可以通過配置文件來創建對象進行依賴注入也可以通過註解的方式來完成,在企業中這兩種方式通常是一起使用的,對於我們自己定義的類,我們可以使用註解來創建對象和依賴注入,但是如果是其他第三方的類,我們無法在這些類上面添加註解,那就只能通過配置的方式來配置了。
2、常用註解
- @Component:該註解需要定義在類上,表示該類對象需要通過 Spring 來創建,@Component 是一個通用的註解,在每一層都可以使用。
- @Controller:該註解需要定義在控制層的類上,表示該類對象需要通過 Spring 來創建,@Controller 層是 spring mvc 的註解,具有將請求進行轉發,重定向的功能。
- @Service:該註解需要定義在業務層的類上,表示該類對象需要通過 Spring 來創建,這個註解只是標註該類處於業務邏輯層,即帶有額外標識的公共,表明這是業務邏輯層。
- @Repository:該註解需要定義在數據層的類上,表示該類對象需要通過 Spring 來創建,還註解還具有將數據庫操作拋出的原生異常翻譯轉化爲 Spring 的持久層異常的功能。
上述4個註解的作用等同於<bean>
標籤,在使用這些註解時可以傳入一個字符串作爲 bean id,如果沒有傳入 bean id 則默認 bean id 等於類名首字母小寫。
- @Autowired:該註解需要定義在類的屬性之上,表示該屬性的值需要由spring進行注入。
- @Resource:該註解需要定義在類的屬性之上,表示該屬性的值需要由spring進行注入。
上述兩個註解用於進行依賴注入,只不過 @Autowired 優先按屬性類型自動注入,而 @Resource 優先按屬性名稱自動注入。
@Resource 有兩個屬性是比較重要的,分是 name 和 type,Spring 將 @Resource 註解的 name 屬性作爲 bean id 去容器中查找,而 type 屬性則解析爲 bean 的類型。所以如果使用 name 屬性,則優先通過屬性名稱自動注入,而使用 type 屬性時則使用類型匹配自動注入策略。如果既不指定 name 也不指定 type 屬性,這時將通過優先用過屬性名稱自動注入策略。無論使用 @Resource 還是 @AutoWired 如果匹配策略是按照類型匹配,這時 Spring 容器中有超過1個相同類型對象時,就會出現異常。
最後,如果使用了註解的方式,那麼需要在 applicationContext.xml 中聲明添加了註解的這些類所在的包名,這樣 Spring 才能去掃描這些包,如果不配置註解將不生效。配置方式如下:
<context:component-scan base-package="com.spring.demo2"></context:component-scan>
注意:使用Spring時,通過註解和通過配置文件創建的對象都保存在了Spring容器中,所以既可以使用註解的方式來完成依賴注入,也可以使用<property>
標籤進行注入。換句話講,我們在配置文件中通過<bean>
標籤創建的對象,可以使用註解的方式來注入,使用註解的方式創建的對象也可以使用<property>
標籤來注入。
3、註解版 IOC 示例
(1)service 層
@Service
public class UserService {
@Resource
private UserDao userDao;
public void select() {
System.out.println("正在執行查詢業務");
userDao.select();
}
}
(2)dao層
@Repository
public class UserDao {
@Resource
private DataSource dataSource;
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void select() {
System.out.println("執行新增數據");
Connection conn = null;
PreparedStatement ps = null;
try {
conn = dataSource.getConnection();
String sql = "select * from products";
ps = conn.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
while(resultSet.next()) {
System.out.println(resultSet.getInt("p_id") + "\t" +
resultSet.getString("p_name") + "\t" +
resultSet.getDouble("p_price") + "\t" +
resultSet.getInt("p_count") + "\t" +
resultSet.getString("p_class") + "\t" +
resultSet.getString("p_attribute"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
(3)applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:cache="http://www.springframework.org/schema/cache"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<context:component-scan base-package="com.spring.demo2"></context:component-scan>
<!-- 創建連接池 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!--提供數據庫連接信息和連接池的常用信息-->
<!--驅動類-->
<property name="driverClass" value="${jdbc.driverClass}" />
<!--連接數據庫的地址-->
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<!--連接數據庫的用戶名-->
<property name="user" value="${jdbc.user}" />
<!--連接數據庫的密碼-->
<property name="password" value="${jdbc.password}" />
<!--最大連接數-->
<property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
<!--最小連接數-->
<property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
<!--初始化連接數-->
<property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
<!--自增長連接數-->
<property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
<!--連接對象空閒時間 超出10分鐘銷燬-->
<property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
<!--連接數據庫的等待時間 超出等待時間 拋出異常-->
<property name="checkoutTimeout" value="${c3p0.checkoutTimeout}"></property>
<!--檢查連接的間隔時間-->
<property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"></property>
</bean>
<!-- 創建資源文件加載器對象 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:c3p0.properties"></property>
</bean>
</beans>
(4)測試類:Action類
public class UserAction{
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("spring2.xml");
UserService service = (UserService) ac.getBean("userService");
service.select();
}
}