其他分享
首页 > 其他分享> > 开源项目学习-jeesite1.2.7-UserUtils

开源项目学习-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=&lt=&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。

以上问题答案来自:

DisposableBean

这是啥?有啥用?

Spring应用手册-DisposableBean接口

标签:ApplicationContext,applicationContext,Spring,UserUtils,开源,static,SpringContextHo
来源: https://www.cnblogs.com/sk-lqbzblogs/p/16452491.html