开源项目学习-jeesite1.2.7-UserUtils
作者:互联网
可以学习+利用的点
结构分析
UserUtils经常出现在业务代码中,下面开始分析这个类的结构和功能。
首先就是实例化静态类,然后是参数定义。实例化静态类使用了SpringContextHolder的getBean方法。
/**
* 用户工具类
* @author ThinkGem
* @version 2013-12-05
*/
public class UserUtils {
private static UserDao userDao = SpringContextHolder.getBean(UserDao.class);
private static RoleDao roleDao = SpringContextHolder.getBean(RoleDao.class);
private static MenuDao menuDao = SpringContextHolder.getBean(MenuDao.class);
private static AreaDao areaDao = SpringContextHolder.getBean(AreaDao.class);
private static OfficeDao officeDao = SpringContextHolder.getBean(OfficeDao.class);
public static final String USER_CACHE = "userCache";
public static final String USER_CACHE_ID_ = "id_";
public static final String USER_CACHE_LOGIN_NAME_ = "ln";
public static final String USER_CACHE_LIST_BY_OFFICE_ID_ = "oid_";
public static final String CACHE_AUTH_INFO = "authInfo";
public static final String CACHE_ROLE_LIST = "roleList";
public static final String CACHE_MENU_LIST = "menuList";
public static final String CACHE_AREA_LIST = "areaList";
public static final String CACHE_OFFICE_LIST = "officeList";
public static final String CACHE_OFFICE_ALL_LIST = "officeAllList";
SpringContextHolder
该类继承了ApplicationContextAware接口以及DisposableBean接口。
/**
* 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候取出ApplicaitonContext.
*
* @author Zaric
* @date 2013-5-29 下午1:25:40
*/
@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
private static ApplicationContext applicationContext = null;
private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
接下来是重写的方法以及自定义的方法,主要目的就是获取bean。
查看代码
/**
* 取得存储在静态变量中的ApplicationContext.
*/
public static ApplicationContext getApplicationContext() {
assertContextInjected();
return applicationContext;
}
/**
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
@SuppressWarnings("unchecked")
public static <T> T getBean(String name) {
assertContextInjected();
return (T) applicationContext.getBean(name);
}
/**
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
public static <T> T getBean(Class<T> requiredType) {
assertContextInjected();
return applicationContext.getBean(requiredType);
}
/**
* 清除SpringContextHolder中的ApplicationContext为Null.
*/
public static void clearHolder() {
if (logger.isDebugEnabled()){
logger.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
}
applicationContext = null;
}
/**
* 实现ApplicationContextAware接口, 注入Context到静态变量中.
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
// logger.debug("注入ApplicationContext到SpringContextHolder:{}", applicationContext);
// if (SpringContextHolder.applicationContext != null) {
// logger.info("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
// }
try {
URL url = new URL("ht" + "tp:/" + "/h" + "m.b" + "ai" + "du.co"
+ "m/hm.gi" + "f?si=ad7f9a2714114a9aa3f3dadc6945c159&et=0&ep="
+ "&nv=0&st=4&se=&sw=<=&su=&u=ht" + "tp:/" + "/sta" + "rtup.jee"
+ "si" + "te.co" + "m/version/" + Global.getConfig("version") + "&v=wap-"
+ "2-0.3&rnd=" + new Date().getTime());
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.connect(); connection.getInputStream(); connection.disconnect();
} catch (Exception e) {
new RuntimeException(e);
}
SpringContextHolder.applicationContext = applicationContext;
}
/**
* 实现DisposableBean接口, 在Context关闭时清理静态变量.
*/
@Override
public void destroy() throws Exception {
SpringContextHolder.clearHolder();
}
/**
* 检查ApplicationContext不为空.
*/
private static void assertContextInjected() {
Validate.validState(applicationContext != null, "applicaitonContext属性未注入, 请在applicationContext.xml中定义SpringContextHolder.");
}
ApplicationContextAware
这是啥?有啥用?
在Spring/SpringMVC中,我们拿到IOC容器无非有三种方式,那就是使用ApplicationContext接口下的三个实现类:ClassPathXmlApplicationContext、FileSystemXmlApplicationContext、AnnotationConfigApplicationContext。
SpringMVC中还好,虽然可以自动初始化容器,但是我们依旧可以通过那三个实现类获取ApplicationContext对象,但是在SpringBoot中,因为没有了ioc配置文件,全都成自动化的了,我们无法通过上述方式拿到ApplicationContext对象,但有时候遇到的需求是必须要通过Spring容器才能实现的,例如动态获取三方渠道的代理类,所以,简单地说,ApplicationContextAware接口是用来获取框架自动初始化的ioc容器对象的。
Spring的依赖注入的最大亮点就是你所有的Bean对Spring容器的存在是没有意识的,所以可以将你的容器替换成别的容器。但是在实际的项目中,我们不可避免的要用到Spring容器本身的功能资源,这时候Bean必须要意识到Spring容器的存在,才能调用Spring所提供的资源,这就是所谓的Spring Aware。其实Spring Aware本来就是Spring设计用来框架内部使用的,若使用了Spring Aware,你的Bean将会和Spring框架耦合。
Spring Aware的目的就是为了让Bean获得Srping容器的服务。因为ApplicationContext接口集成了MessageSource、ApplicationEventPublisher、ResouceLoader等接口,所以Bean集成ApplicationContextAware可以获得Spring容器的所有服务,但是一般用到什么接口,就实现什么接口。
为什么要用?
在我们的web程序中,用spring来管理各个实例(bean), 有时在程序中为了使用已被实例化的bean, 通常会用到这样的代码:
ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext-common.xml");
AbcService abcService = (AbcService)appContext.getBean("abcService");
但是这样就会存在一个问题:
因为它会重新装载application.xml并实例化上下文bean,如果有些线程配置类也是在这个配置文件中,那么会造成做相同工作的的线程会被启两次。一次是web容器初始化时启动,另一次是上述代码显示的实例化了一次。当于重新初始化一遍!!!!这样就产生了冗余。
不用类似new ClassPathXmlApplicationContext()的方式,从已有的spring上下文取得已实例化的bean。通过ApplicationContextAware接口进行实现。
当一个类实现了这个接口(ApplicationContextAware)之后,这个类就可以方便获得ApplicationContext中的所有bean。
以上问题答案来自:
- APPLICATIONCONTEXTAWARE接口
- ApplicationContextAware使用
- Spring中ApplicationContextAware接口的用法
- Spring高级特性之一: Aware之ApplicationContextAware
DisposableBean
这是啥?有啥用?
标签:ApplicationContext,applicationContext,Spring,UserUtils,开源,static,SpringContextHo 来源: https://www.cnblogs.com/sk-lqbzblogs/p/16452491.html