最近有同学在使用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