一.在web.xml中配置spring监听器
<!-- Spring容器启动监听器配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>com.test.util.LoadSystemArgsListener</listener-class>
</listener>
缺点:
mvc-dispatcher-servlet.xml配置需要拆分成spring-config.xml和mvc-config.xml,否则系统报错
因为<bean/>放到mvc里了,所以在spring启动的时候找不到对应的bean报错
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'authController': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userService': Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'alias' threw exception;
二.实现InitializingBean接口
1.重写方法afterPropertiesSet()即可
2.增加初始方法配置bean
<bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>
类AbstractAutowiredCapableBeanFactory的invokeInitMethods()源码如下:
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
//判断该bean是否实现了实现了InitializingBean接口,如果实现了InitializingBean接口,则只掉调用bean的afterPropertiesSet方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
//直接调用afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
return null;
}
},getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//直接调用afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
//判断是否指定了init-method方法,如果指定了init-method方法,则再调用制定的init-method
if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//进一步查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
总结:
1、实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率要高一点,但是init-method方式消除了对spring的依赖。
2、如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。