详解获取Spring中bean的工具类封装和bean管理

最近有同学在使用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生命周期图:
bean生命周期
bean生命周期

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

详解获取Spring中bean的工具类封装和bean管理

: » 详解获取Spring中bean的工具类封装和bean管理

原创文章,作者:506227337,如若转载,请注明出处:https://blog.ytso.com/251447.html

(0)
上一篇 2022年5月3日
下一篇 2022年5月3日

相关推荐

发表回复

登录后才能评论