在使用SSH框架进行JavaWeb开发过程中,偶尔会遇到如下问题:
1、需要在Java类中(如:Servlet)获取spring自动装配的bean(如:serviceBean)对象,进行业务处理;
2、需要在Java类中,人为调用service或dao层对象,但是目标对象中依赖spring注入的对象均为null;
一、如何获取spring自动装配的bean对象:
自定义工具类SpringBeanUtil,并实现spring的ApplicationContextAware接口的setApplicationContext方法,spring会在加载的时候扫描到这个类,并将ApplicationContext对象填充进来。
package com.service.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* SpringBeanUtil 用于获取spring注入的bean对象
* @author xuhu
*
*/
@Component //@Component 注解 表示这个类是spring的一个组件
public class SpringBeanUtil implements ApplicationContextAware
{
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
{
SpringBeanUtil.applicationContext = applicationContext;
}
/**
* 获取clazz类对应的spring创建的bean对象
* @param clazz
* @return
*/
public static <T> T getBean(Class<T> clazz)
{
return (T) applicationContext.getBean(clazz);
}
}
接下来,我们就可以在需要获取bean的地方调用SpringBeanUtil工具类获取bean了:
IBean bean = SpringBeanUtil.getBean(BeanImple.class);
需要注意的是:
1、SpringBeanUtil类必须在spring配置文件的指定扫描文件夹内:
<!--检测注解-->
<context:component-scan base-package="com.service" />
2、SpringBeanUtil类 必须加入@Component注解。
二、需要在Java类中,人为调用service或dao层对象
如:在Servlet中需要调用ServiceImpl类进行业务操作
ServiceImpl类如下:
@Service
public class ServiceImpl implements IService
{
@Autowired
IUserDao userDao;
@Autowired
IUserTypeLeverDao userTypeLeverDao;
public List<User> searchUserList()
{
return userDao.searchUserList();
}
}
如果直接在Servlet中new ServiceImpl对象,则userDao对象及userTypeLeverDao均为null,
public void invokeService1()
{
new ServiceImpl();
}
当然我们可以这么做 在searchUserList方法中显示的获取spring创建的userDao:
@Service
public class ServiceImpl implements IService
{
@Autowired
IUserDao userDao;
@Autowired
IUserTypeLeverDao userTypeLeverDao;
public List<User> searchUserList()
{
//使用SpringBeanUtil工具类获取bean
userDao = SpringBeanUtil.getBean(IUserDao.class);
return userDao.searchUserList();
}
}
以上做法能解决问题,但是不够优雅,如果ServiceImpl中含有多个dao,那是不是每一个dao都得通过工具类获取一下,是不是很麻烦?
如果在Servlet中,获取需要调用的ServiceImpl类的spring自动装配的对象,再使用反射则可以使代码更优雅:
public void invokeService2()
{
Class<ServiceImpl> clazz = ServiceImpl.class;
//获取ServiceImpl的spring注入的bean对象
ServiceImpl service = SpringBeanUtil.getBean(clazz);
//调用searchUserList
Method method = clazz.getDeclaredMethod("searchUserList");
method.invoke(service);
}
而在ServiceImpl的searchUserList方法中也不需要显示获取spring创建的 userDao;
@Service
public class ServiceImpl implements IService
{
@Autowired
IUserDao userDao;
@Autowired
IUserTypeLeverDao userTypeLeverDao;
public List<User> searchUserList()
{
//无需使用SpringBeanUtil工具类获取bean
//userDao = SpringBeanUtil.getBean(IUserDao.class);
return userDao.searchUserList();
}
}