今天在项目中写代码,遇到两个Spring的问题,记录一下。再一次看到了spring的灵活之处。
1、@Autowired没有生效
打算用unitils来搞一下单元测试,于是搞了一个spring的xml文件,里面配置了几个Bean,然后用unitils的注解搞了(为啥用这个?主要是考虑少写点代码,以前是直接用ClassPath***ApplicationContext来搞的),但是发现有的bean里面引用了别的bean,是通过Autowired来搞的,没有写属性的set方法,但是在实际运行中,抛出来空指针。
A、刚开始以为是这个框架的问题,换了一个框架,问题还是一样,于是有还原回去了
B、以为是spring的配置文件的问题,再三review了一下,发现没有大问题
C、打算在xml中显示的配制出,如果A Bean依赖了B Bean那就再properties中配置,但是没有set属性,所以还是不行
D、加一个set属性就行了吧?但是就是不想写,于是继续寻找方法
E、当时好奇为啥web容器启动能够找到,但是单元测试就不行呢?
1
2
3
4
5
6
|
import
org.unitils.UnitilsJUnit4;
import
org.unitils.spring.annotation.SpringApplicationContext;
@SpringApplicationContext
({
"/configcenter-spring.xml"
})
public
class
BaseTestCase
extends
UnitilsJUnit4 {
}
|
怎么解决的?
继续在google中寻找答案,最终原因是,如果要使用@Autowired的话,需要配置一个Bean
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
这个Bean是负责装载@Autowired的注解的Bean的。
为啥web容器中不用显示的配置呢?
应该是web框架在启动的时候,把这个bean注入到Spring容器中了。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.unitils</groupId>
<artifactId>unitils</artifactId>
<version>2.2</version>
<scope>test</scope>
</dependency>
2、抛出异常java.lang.reflect.MalformedParameterizedTypeException
这个是在Spring中集成Activiti,遇到的是抛出了这个异常。
刚开始在网上找,走弯路了,直接在google中输入的这个异常,很多是不相关的答复,但是有文章说是spring 3 和 spring 2.X的问题。
仔细看了一下,确实是spring3,于是排除spring3,用系统中默认的spring 2.5.6.
但是,还是不行,为啥呢?
抛出异常的配置文件
-
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
-
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
-
</bean>
于是继续找,在这里找到了答案:http://blog.csdn.net/ie8848520/article/details/8634479
原来是FactoryBean中,在2.5的时候还不支持泛型,在3.x的时候支持了泛型FactoryBean<T>,ProcessEngineFactoryBean继承了FactoryBean,但是使用了泛型,于是在spring 2.5的环境中就抛出了异常。
那咋办呢?
不能让整体的spring从2.5升级到3.x吧,毕竟系统升级这个还是有风险的。
换了一个配置,做了一个适配。
ProcessEngineFactoryBean中的getObject是调用了:
processEngine = (ProcessEngineImpl) processEngineConfiguration.buildProcessEngine();
那就直接用这个buildProcessEngine吧。
1
2
3
4
5
6
7
8
9
|
<!-- 由于spring2.5的FactoryBean不支持泛型,所以没法通过ProcessEngineFactoryBean来构建 -->
<
bean
id
=
"processEngine"
factory-bean
=
"processEngineConfiguration"
factory-method
=
"buildProcessEngine"
> </
bean
>
<
bean
id
=
"repositoryService"
factory-bean
=
"processEngineConfiguration"
factory-method
=
"getRepositoryService"
/>
<
bean
id
=
"runtimeService"
factory-bean
=
"processEngineConfiguration"
factory-method
=
"getRuntimeService"
/>
<
bean
id
=
"identityService"
factory-bean
=
"processEngineConfiguration"
factory-method
=
"getIdentityService"
/>
<
bean
id
=
"taskService"
factory-bean
=
"processEngineConfiguration"
factory-method
=
"getTaskService"
/>
<
bean
id
=
"historyService"
factory-bean
=
"processEngineConfiguration"
factory-method
=
"getHistoryService"
/>
<
bean
id
=
"managementService"
factory-bean
=
"processEngineConfiguration"
factory-method
=
"getManagementService"
/>
|
spring的灵活强大之处再一次体现出来了。。。