虽然我们可以通过 @Autowired 在 Bean 类中使用自动注入功能,但是 Bean 还是在 applicatonContext.xml 文件中通过 <bean> 进行定义 —— 在前面的例子中,我们还是在配置文件中定义 Bean,通过 @Autowired为 Bean 的成员变量、方法形参或构造函数形参提供自动注入的功能。
新的applicaitonContext.xml 配置文件中蓝色的部分就是原来的<bean>的注入方式,现在已经给屏蔽了。不需要再写。而红色部分就是使用了<context:component-scan base-package ="com.firemax"/> ,让spirng自动搜索,然后注入。
扫描过滤方式
通过 @Scope 指定 Bean 的作用范围
在所有的JPOPO中,我们可以使用@Entity 这个注解来注入 JOPO。这样我们在 Persistent.xml中就不需要在 定义哪些POJO的类了。
那么能不是也可以通过注解定义 Bean,从 XML 配置文件中完全移除 Bean 定义的配置呢?
答案是肯定的,我们通过 Spring 2.5 提供的 @Component 注释就可以达到这个目标了。
修改Bean的java类的代码如下,在类名前面加上 @Component注解
- package
com.firemax.test.service; - 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.LocalEntityManagerFactor yBean"> -
<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.AutowiredAnnotationBeanP ostProcessor"/> -
--> -
<!-- <context:component-scan/> 配置项不但启用了对类包进行扫描以实施注释驱动 Bean 定义的功能,同时还启用了注释驱动自动注入的功能(即还隐式地在内部注册了 AutowiredAnnotationBeanP ostProcessor 和 CommonAnnotationBeanPost Processor),因此当使用 <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>
注意:
- 这里注入的bean 的名称是按照类的名称,把第一个字母改成小写来命名的。比如例子中的CountryService的bean的名称就是countryService.
- 我们也可以通过@Component("countryService") 这种方式来显示的定义一个bean的注入名称。但是在大多数情况下没有必要。
<context:component-scan/> 的 base-package 属性指定了需要扫描的类包,类包及其递归子包中所有的类都会被处理。
<context:component-scan/> 还允许定义过滤器将基包下的某些类纳入或排除。Spring 支持以下 4 种类型的过滤方式,通过下表说明:
过滤器类型 | 说明 |
---|---|
注释 | 假如 com.firemax.test.SomeAnnotation 是一个注释类,我们可以将使用该注释的类过滤出来。 |
类名指定 | 通过全限定类名进行过滤,如您可以指定将 |
正则表达式 | 通过正则表达式定义过滤的类,如下所示: com/.firemax/.test/.Default.* |
AspectJ 表达式 | 通过 AspectJ 表达式定义过滤的类,如下所示: com. firemax.test..*Service+ |
下面是一个简单的例子:
|
默认情况下通过 @Component
@Scope
|
这样,当从 Spring 容器中获取 boss
在Spring2.5中引入了更多的典型化注解,@Repository ,@Service,@Controler是@Component的细化。分别表示持久层,服务层,控制层。建议使用这个注解来取代@Component
附上一个java Applicaiton的简单测试程序
- package
com.firemax.test.tester; - import
java.util.Iterator; - import
org.springframework.context.ApplicationContext; - import
org.springframework.context.support.FileSystemXmlApplication Context; - 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 { -
-
public static void main(String[] args) throws Exception{ -
// TODO Auto-generated method stub -
ApplicationContext ctx = new FileSystemXmlApplication Context("/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); -
-
} - }
感谢 JPA 感谢Spring ,终于不要频繁的去定义和修改这些Bean了