最近有同学在使用Spring的bean管理时,出现了很严重的问题,项目在每次重启时,都会抛出找不到applicationContext.xml的异常。究其原因是对web.xml的加载顺序不理解和对src的错误理解导致的,现将经验分享给大家!
java项目的目录结构
java项目中一般有两个重要的目录,一个是src,一个是bin。
src:是源文件source的意思,存放程序员的代码的地方(.java文件),项目发布或打包后不会存在该目录.
bin:存放生成的字节码.class文件的地方,项目编译,打包后存在.
现在我们应该知道了在项目发布后是不会存在src目录的,因此不要写System.getProperty("user.dir")+"//src//applicationContext.xml";类似的代码,以免被大家嘲笑!
web.xml加载顺序
为什么我要说web.xml的加载顺呢?这个主要和我们实现bean管理工具类有关。如果你不知道web.xml的加载顺序,不知道原理,那么在实现上可能就会出现问题。
真正的加载顺序为:context-param -> listener -> filter -> servlet。当然同类型的,会按照配置顺序加载,另外还可以配置<load-on-startup>5</load-on-startup>来指定加载的顺序。
Spring的bean管理工具类
1.ApplicationContextAware
通过ApplicationContextAware接口,我们来实现bean的管理工具类的封装,代码如下:
public class SpringContextUtil implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
然后在spring的配置文件中配置即可
<bean class="com.xttblog.SpringContextUtil" lazy-init="false" />
2.SpringBeanAutowiringSupport
通过SpringBeanAutowiringSupport抽象类来实现。代码如下:
public class SpringWiredBean extends SpringBeanAutowiringSupport {
/**
* 自动装配注解会让Spring通过类型匹配为beanFactory注入示例
*/
@Autowired
private BeanFactory beanFactory;
private SpringWiredBean() {}
private static SpringWiredBean instance;
static {
// 静态块,初始化实例
instance = new SpringWiredBean();
}
/**
* 实例方法
* 使用的时候先通过getInstance方法获取实例
* @param beanId
* @return
*/
public Object getBeanById(String beanId) {
return beanFactory.getBean(beanId);
}
public static SpringWiredBean getInstance() {
return instance;
}
}
需要注意这里使用了自动装配,所以spring配置文件中不能少了下面的配置
<context:component-scan base-package="com.xttblog"></context:component-scan>
3.BeanFactoryAware
通过BeanFactoryAware接口来实现,代码如下:
@Service
public class SpringBeanUtils implements BeanFactoryAware {
private static BeanFactory beanFactory;
/**
* 注入BeanFactory实例
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
SpringBeanUtils.beanFactory = beanFactory;
}
/**
* 根据bean的名称获取相应类型的对象
*
* @param beanName
* bean的名称
* @return Object类型的对象
*/
public static Object getBean(String beanName) {
return beanFactory.getBean(beanName);
}
}
这里也需要在spring配置文件中装配,和2一样,我就不在单独写了!
以上3中都可以通过XXDAO xxDao =(XXDAO)SpringBeanUtils.getContext().getBean("xxDAO");的形式获取对象。
获取bean对象
方法一:在手动加载xml初始化时获取ApplicationContext
通过ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、PathmatchingResourceResolver、FileSystemResource等方式加载spring配置文件的方式实现
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
方法二:通过Spring提供的工具类获取ApplicationContext对象
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);
ac1.getBean("beanId");
ac2.getBean("beanId");
方法三:继承自抽象类ApplicationObjectSupport
抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取ApplicationContext
方法四:继承自抽象类WebApplicationObjectSupport
调用getWebApplicationContext()获取WebApplicationContext
方法五:通过Spring提供的ContextLoader
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext(); wac.getBean(beanID);
下面附一张spring的bean生命周期图:


版权声明:本文为博主原创文章,未经博主允许不得转载。

: » 详解获取Spring中bean的工具类封装和bean管理
原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/tech/java/251447.html