註解的力量 -----Spring 2.5 JPA hibernate 使用方法的點滴整理(五):使用@Component 來簡化bean的配置...

雖然我們可以通過 @Autowired 在 Bean 類中使用自動注入功能,但是 Bean 還是在 applicatonContext.xml 文件中通過 進行定義 —— 在前面的例子中,我們還是在配置文件中定義 Bean,通過 @Autowired爲 Bean 的成員變量、方法形參或構造函數形參提供自動注入的功能。
那麼能不是也可以通過註解定義 Bean,從 XML 配置文件中完全移除 Bean 定義的配置呢?
答案是肯定的,我們通過 Spring 2.5 提供的 @Component 註釋就可以達到這個目標了。
修改Bean的java類的代碼如下,在類名前面加上 @Component註解


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import com.firemax.test.hibernate.AlcorTCitys;
import com.firemax.test.hibernate.AlcorTCitysDAO;
import com.firemax.test.hibernate.AlcorTCountries;
import com.firemax.test.hibernate.AlcorTCountriesDAO;
import com.firemax.test.hibernate.AlcorTProvinces;
import com.firemax.test.hibernate.AlcorTProvincesDAO;
import com.firemax.test.hibernate.AlcotTDistrict;
import com.firemax.test.hibernate.AlcotTDistrictDAO;

@Component
public class CountryService {
private static Log logger = LogFactory.getLog(CountryService.class);
@Autowired
private AlcorTCountriesDAO alcorTCountriesDAO;
@Autowired
private AlcorTProvincesDAO alcorTProvincesDAO;
@Autowired
private AlcorTCitysDAO alcorTCitysDAO;
@Autowired
private AlcotTDistrictDAO alcotTDistrictDAO;

public CountryService(){

}
//這裏是業務邏輯的方法
。。。。。
}


然後,我們修改配置文件applicatonContext.xml中,啓用自動注入的功能,而放棄原來的<bean>方式的配置


<?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:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"
default-autowire="autodetect">
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="testerPU" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<!-- 事務攔截器bean需要依賴注入一個事務管理器 -->
<property name="transactionManager">
<ref local="transactionManager" />
</property>
<property name="transactionAttributes">
<!-- 下面定義事務(指service裏面的方法)傳播屬性 -->
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="save*">PROPAGATION_REQUIRED</prop>
<prop key="add*">PROPAGATION_REQUIRED</prop>
<prop key="update*">PROPAGATION_REQUIRED</prop>
<prop key="remove*">PROPAGATION_REQUIRED</prop>
<prop key="delete*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="find*">PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="load*">PROPAGATION_REQUIRED,readOnly
</prop>
<prop key="change*">PROPAGATION_REQUIRED</prop>
<prop key="count*">PROPAGATION_REQUIRED</prop>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>

<!-- 該 BeanPostProcessor 將自動對標註 @Autowired 的 Bean 進行注入 -->
<!-- 這個Processor 已經被 <context:annotation-config/> 所簡化
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
-->
<!-- <context:component-scan/> 配置項不但啓用了對類包進行掃描以實施註釋驅動 Bean 定義的功能,同時還啓用了註釋驅動自動注入的功能(即還隱式地在內部註冊了 AutowiredAnnotationBeanPostProcessor 和 CommonAnnotationBeanPostProcessor),因此當使用 <context:component-scan/> 後,就可以將 <context:annotation-config/> 移除了。 -->
<context:component-scan base-package ="com.firemax"/>


<!-- 定義自動代理BeanNameAutoProxyCreator -->
<bean id="beanNameAutoProxyCreator"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<!-- 指定對滿足哪些bean name的bean自動生成業務代理 -->
<property name="beanNames">
<list>
<value>*Service</value>
</list>
</property>
<!-- 下面定義BeanNameAutoProxyCreator所需的事務攔截器 -->
<property name="interceptorNames">
<list>
<!-- 此處可增加其他新的Interceptor -->
<value>transactionInterceptor</value>
</list>
</property>
</bean>
<!--
<bean id="AlcorTCountriesDAO" class="com.firemax.test.hibernate.AlcorTCountriesDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="AlcorTProvincesDAO" class="com.firemax.test.hibernate.AlcorTProvincesDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="AlcotTDistrictDAO" class="com.firemax.test.hibernate.AlcotTDistrictDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="AlcorTCitysDAO" class="com.firemax.test.hibernate.AlcorTCitysDAO">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<bean id="CountryService" class="com.firemax.test.service.CountryService"/>
-->
</beans>


新的applicaitonContext.xml 配置文件中藍色的部分就是原來的<bean>的注入方式,現在已經給屏蔽了。不需要再寫。而紅色部分就是使用了<context:component-scan base-package ="com.firemax"/> ,讓spirng自動搜索,然後注入。


注意:
這裏注入的bean 的名稱是按照類的名稱,把第一個字母改成小寫來命名的。比如例子中的CountryService的bean的名稱就是countryService.

我們也可以通過@Component("countryService") 這種方式來顯示的定義一個bean的注入名稱。但是在大多數情況下沒有必要。


<context:component-scan/> 的 base-package 屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會被處理。

<context:component-scan/> 還允許定義過濾器將基包下的某些類納入或排除。Spring 支持以下 4 種類型的過濾方式,通過下表說明:

掃描過濾方式
過濾器類型 說明
註釋 假如 com.firemax.test.SomeAnnotation 是一個註釋類,我們可以將使用該註釋的類過濾出來。
類名指定 通過全限定類名進行過濾,如您可以指定將 com.firemax.test.IncludeService納入掃描,而將 com.firemax.test.NotIncludeService 排除在外。
正則表達式 通過正則表達式定義過濾的類,如下所示: com\.firemax\.test\.Default.*
AspectJ 表達式 通過 AspectJ 表達式定義過濾的類,如下所示: com. firemax.test..*Service+

下面是一個簡單的例子:

<context:component-scan base-package="com.firemax"> <context:include-filter type="regex" expression="com\.firemax\.test\.service\..*"/> <context:exclude-filter type="aspectj" expression="com.firemax.test.util..*"/></context:component-scan>

默認情況下通過 @Component 定義的 Bean 都是 singleton 的,如果需要使用其它作用範圍的 Bean,可以通過 @Scope 註釋來達到目標,如以下代碼所示:

通過 @Scope 指定 Bean 的作用範圍
package com.firemax.tester.service;import org.springframework.context.annotation.Scope;…@Scope("prototype")@Component("countryService")public class CountryService{ …}

這樣,當從 Spring 容器中獲取 boss Bean 時,每次返回的都是新的實例了。


在Spring2.5中引入了更多的典型化註解,@Repository ,@Service,@Controler是@Component的細化。分別表示持久層,服務層,控制層。建議使用這個註解來取代@Component


附上一個java Applicaiton的簡單測試程序

import java.util.Iterator;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.firemax.test.hibernate.AlcorTCitys;
import com.firemax.test.hibernate.AlcorTCitysDAO;
import com.firemax.test.hibernate.AlcorTCountries;
import com.firemax.test.hibernate.AlcorTProvinces;
import com.firemax.test.hibernate.AlcotTDistrict;
import com.firemax.test.hibernate.AlcotTDistrictDAO;
import com.firemax.test.service.CountryService;


public class Tester {

/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
ApplicationContext ctx = new FileSystemXmlApplicationContext("/WebContent/WEB-INF/classes/applicationContext*.xml");
String[] beans = ctx.getBeanDefinitionNames();
for (int i = 0 ; i < beans.length;i++)
{
System.out.println(beans[i]);
}
CountryService countryService= (CountryService)ctx.getBean("countryService");

AlcorTCountries alcorTCountries= countryService.getCountriesInfo("CN");
System.out.println(alcorTCountries.getCountry());
System.out.println("開始調用子類");
System.out.println(alcorTCountries.getAlcorTProvinceses().size());
Iterator<AlcorTProvinces> it = alcorTCountries.getAlcorTProvinceses().iterator();
while (it.hasNext()){
AlcorTProvinces alcorTProvinces= (AlcorTProvinces)it.next();
System.out.println(alcorTProvinces.getProvinceName());
}
AlcotTDistrict alcotTDistrict= new AlcotTDistrict();
alcotTDistrict.setDistrictCode("22");
alcotTDistrict.setDistrictName("浦東");
AlcorTCitys alcorTCitys =countryService.getCityInfo("021");
alcotTDistrict.setAlcorTCitys(alcorTCitys);
countryService.saveProvinces(alcotTDistrict);

}
}


在所有的JPOPO中,我們可以使用@Entity 這個註解來注入 JOPO。這樣我們在 Persistent.xml中就不需要在 定義哪些POJO的類了。

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/remote_roamer
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章