zoukankan      html  css  js  c++  java
  • 在普通类里面不能通过@Autowire自动注入service,那么如何调用需要自动注入的service呢?

    在Spring管理的web项目里,配置好之后,就可以直接通过@Autowire自动注入获得service;

    但是在普通Java类中使用service或者dao就会报空指针异常,因为这个普通类不在Spring的管理下,所以不能使用Spring来注入。

    下面讲一下一个普通的Java类如何使用service

    先定义SpringContextHolder

    package com.fan.framework.context;
    
    import org.apache.commons.lang3.Validate;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.DisposableBean;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.stereotype.Service;
    
    /**
     * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候取出ApplicaitonContext.*/
    @Service
    @Lazy(false)
    public class SpringContextHolder implements ApplicationContextAware, DisposableBean {
    
        private static ApplicationContext applicationContext = null;
    
        private static Logger logger = LoggerFactory.getLogger(SpringContextHolder.class);
    
        /**
         * 取得存储在静态变量中的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);
    //        }
            
            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.");
        }
        
        
    }

    然后再使用SpringContextHolder获取指定的service

    package com.thinkgem.jeesite.modules.sys.utils;
    
    import java.util.Calendar;
    import java.util.HashMap;
    import java.util.Map;
    import javax.servlet.http.HttpServletRequest;
    import me.chanjar.weixin.common.exception.WxErrorException;
    import me.chanjar.weixin.cp.api.WxCpConfigStorage;
    import me.chanjar.weixin.cp.api.WxCpService;
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    import org.apache.commons.lang3.StringUtils;
    import com.fan.framework.context.SpringContextHolder;
    import com.fan.modules.sys.entity.User;
    import com.fan.modules.sys.entity.WechatLog;
    import com.fan.modules.sys.service.WechatLogService;
    import com.thinkgem.jeesite.common.utils.Exceptions;
    
    /**
     * 微信日志*/
    public class WechatLogUtils {
        
        private static WechatLogService wechatLogService = SpringContextHolder.getBean(WechatLogService.class);
        
        /**
         * 保存日志
         * @param request
         * @param wxCpService
         * @param wxCpConfigStorage
         * @param qyWechat            微信号名称
         * @param title                操作菜单名称
         * @param user                用户,可为空
         * @param handler
         * @param e                    异常信息
         */
        public static void saveWeChatLog(HttpServletRequest request, WxCpService wxCpService, WxCpConfigStorage wxCpConfigStorage, String qyWechat, String application, String title, String message, User user, Object handler, Exception e) {
            
            WechatLog weChatLog = new WechatLog();
            
            if(StringUtils.isNotBlank(qyWechat)){        // 企业微信
                weChatLog.setQyWechat(qyWechat);
            }
            
            if(StringUtils.isNotBlank(application)){        // 应用
                weChatLog.setApplication(application);
            }
            
            if(null != request && null != wxCpService && null != wxCpConfigStorage){
                weChatLog.setApplication(getAgentName(wxCpService, wxCpConfigStorage));    // 应用
                Map<String, String> map = getMatchedMenu(request, wxCpService, wxCpConfigStorage);
                weChatLog.setFirstLevelMenu(map.get("first_level_menu"));                // 一级菜单
                weChatLog.setSecondLevelMenu(map.get("second_level_menu"));                // 二级菜单
            }
            
            if(null != user){
                weChatLog.setEmployeeNo(user.getLoginName());        // 工号
                weChatLog.setEmployeeName(user.getName());            // 姓名
            }
            
            if(StringUtils.isNotBlank(title)){            // 标题
                weChatLog.setTitle(title);
            }else{
                if(StringUtils.isNotBlank(weChatLog.getApplication())){
                    title = weChatLog.getApplication();
                    if(StringUtils.isNotBlank(weChatLog.getFirstLevelMenu())){
                        title += ("-"+weChatLog.getFirstLevelMenu());
                    }
                    if(StringUtils.isNotBlank(weChatLog.getSecondLevelMenu())){
                        title += ("-"+weChatLog.getSecondLevelMenu());
                    }
                    weChatLog.setTitle(title);
                }
                
            }
            
            Calendar calendar= Calendar.getInstance();
            weChatLog.setCreateDate(calendar.getTime());        // 创建时间
            
            weChatLog.setException(Exceptions.getStackTraceAsString(e));        // 异常消息
            
            if(StringUtils.isNotBlank(message)){
                weChatLog.setMessage(message);
            }
            
            weChatLog.setType(e == null ? WechatLog.TYPE_ACCESS : WechatLog.TYPE_EXCEPTION);    // 日志接入类型(1:接入日志;2:错误日志)
            
            if(null != request){
                weChatLog.setParams(request.getParameterMap());    // 操作提交的数据
                
                weChatLog.setMethod(request.getMethod());        // 提交方式
                
                weChatLog.setUserAgent("");    // 操作用户代理信息
                
                weChatLog.setIp(getRemoteAddr(request));        // ip
                
                weChatLog.setUri(request.getRequestURI());        // uri
            }
            
            // 如果无标题并无异常日志,则不保存信息
            if (StringUtils.isNotBlank(weChatLog.getTitle()) || StringUtils.isNotBlank(weChatLog.getException())){
                // 保存日志信息
                wechatLogService.insert(weChatLog);
            }
            
        }
        /**
         * 获得用户远程地址
         */
        public static String getRemoteAddr(HttpServletRequest request){
            String remoteAddr = request.getHeader("X-Real-IP");
            if (StringUtils.isNotBlank(remoteAddr)) {
                remoteAddr = request.getHeader("X-Forwarded-For");
            }else if (StringUtils.isNotBlank(remoteAddr)) {
                remoteAddr = request.getHeader("Proxy-Client-IP");
            }else if (StringUtils.isNotBlank(remoteAddr)) {
                remoteAddr = request.getHeader("WL-Proxy-Client-IP");
            }
            return remoteAddr != null ? remoteAddr : request.getRemoteAddr();
        }
        
        /**
         * 获取应用
         * https://qyapi.weixin.qq.com/cgi-bin/agent/get?access_token=ACCESS_TOKEN&agentid=AGENTID
         * 返回的是json字符串
         */
        public static String getAgent(WxCpService wxCpService, WxCpConfigStorage wxCpConfigStorage) {
            String accessToken = wxCpConfigStorage.getAccessToken();
            Integer agentId = wxCpConfigStorage.getAgentId();
            String url = "https://qyapi.weixin.qq.com/cgi-bin/agent/get?";
            String info = null;
            try {
                info = wxCpService.get(url, "access_token="+accessToken + "&agentid=" + agentId);
            } catch (WxErrorException e) {
                e.printStackTrace();
            }
            return info;
        }
        
        /**
         * 获取菜单
         * https://qyapi.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN&agentid=AGENTID
         * 返回的是json字符串
         */
        public static String getMenu(WxCpService wxCpService, WxCpConfigStorage wxCpConfigStorage) {
            String accessToken = wxCpConfigStorage.getAccessToken();
            Integer agentId = wxCpConfigStorage.getAgentId();
            String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/get?";
            String menu = null;
            try {
                menu = wxCpService.get(url, "access_token="+accessToken + "&agentid=" + agentId);
            } catch (WxErrorException e) {
                e.printStackTrace();
            }
            return menu;
        }
        
        /**
         * 获取应用中的name
         * @throws WxErrorException
         */
        public static String getAgentName(WxCpService wxCpService, WxCpConfigStorage wxCpConfigStorage) {
            String json = getAgent(wxCpService, wxCpConfigStorage);
            // 响应结果
            JSONObject jsonObject = JSONObject.fromObject(json);
            // name
            String name = (String) jsonObject.get("name");
            return name;
        }
        
        /**
         * 根据uri与获取的菜单相匹配,返回一级菜单和二级菜单
         */
        public static Map<String, String> getMatchedMenu(HttpServletRequest request, WxCpService wxCpService, WxCpConfigStorage wxCpConfigStorage) {
             Map<String, String> matchedMenu = new HashMap<String, String>();
             matchedMenu.put("first_level_menu", "");
             matchedMenu.put("second_level_menu", "");
            String uri = request.getRequestURI();
            if(uri.startsWith("/")){
                uri = uri.replaceFirst("/", "");
            }
            String json = getMenu(wxCpService, wxCpConfigStorage);
            // 响应结果
            JSONObject jsonObject = JSONObject.fromObject(json);
            JSONArray button = jsonObject.getJSONArray("button");
            if(button.size() > 0){
                boolean isBreak = false;
                for (int i = 0; i < button.size(); i++) {
                    JSONObject firstObject = JSONObject.fromObject(button.get(i));
                    JSONArray subButton = firstObject.getJSONArray("sub_button");
                    if(subButton.size() > 0){
                        for(int j = 0 ; j < subButton.size() ; j++){
                            JSONObject secondObject = JSONObject.fromObject(subButton.get(j));
                            String url = (String) secondObject.get("url");
                            if(StringUtils.isNotBlank(url) && url.endsWith(uri)){
                                // 二级菜单的名称
                                String name2 = (String) secondObject.get("name");
                                matchedMenu.put("second_level_menu", name2);
                                // 一级菜单的名称
                                String name1 = (String) firstObject.get("name");
                                matchedMenu.put("first_level_menu", name1);
                                isBreak = true;
                                break;
                            }
                        }
                        if(isBreak){
                            break;
                        }
                    }
                }
            }
            return matchedMenu;
        }
        
    }

    另外一种方法是

    先编写一个类来实现ApplicationContextAware

    /**
     * 通过该类即可在普通工具类里获取spring管理的bean
     */
    public final class SpringTool implements ApplicationContextAware {
        private static ApplicationContext applicationContext = null;
     
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            if (SpringTool.applicationContext == null) {
                SpringTool.applicationContext = applicationContext;
                System.out.println(
                        "========ApplicationContext配置成功,在普通类可以通过调用ToolSpring.getAppContext()获取applicationContext对象,applicationContext="
                                + applicationContext + "========");
            }
        }
     
        public static ApplicationContext getApplicationContext() {
            return applicationContext;
        }
     
        public static Object getBean(String name) {
            return getApplicationContext().getBean(name);
        }
    }

    然后把这个类加到spring的配置文件中去

    <bean class="com.xsl.spring.SpringTool"/>

    这样就可以在任何一个普通的工具类里,根据spring里配置好的bean的id,得到这个注入好的对象了

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = "classpath*:spring/spring-context.xml")
    public class JmFposStoreSalesTest {
        @Test
        public void test() {
            WechatLogService wechatLogService = (WechatLogService) SpringTool.getBean("articleService");
            // 再进行其它操作
            
        }
    }
  • 相关阅读:
    SQL Server中的事务与锁
    delphi中 dataset容易出错的地方
    Ehlib(Delphi控件) v9.2.024 D7-XE10.2 免费绿色特别版
    Delphi (Library Path Browsing Path)
    XML序列化和反序列化
    C#基础--Attribute(标签) 和 reflect(反射) 应用
    C#特性类的使用
    NOPI使用手册
    【WCF】错误处理(四):一刀切——IErrorHandler
    浅析C#中的事件
  • 原文地址:https://www.cnblogs.com/xsl1995/p/9177688.html
Copyright © 2011-2022 走看看