如何从Spring Boot中的一个普通类获取会话?


问题内容

我想从一个普通班上开会。使用@Autowired无效。

public class TMessageHandlerFactory implements MessageHandlerFactory {

    @Autowired
    private HttpSession session;

    @Override
    public void data(InputStream data) {
        int userId = (int)session.getAtrribute("key"); //session null
        ....        //do sth
    }
}

构造函数也没有用

@Component
public class SMTPRunner implements ApplicationRunner {

    @Autowired
    private UserService userService;    // userService can access

    @Autowired
    private HttpSession session;        // session can't access

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {
        TMessageHandlerFactory myFactory = new TMessageHandlerFactory(session);
        ....
    }
}

我也尝试使用SpringBeanFactory,但也没有用。

@Component
public class SpringBeanFactoryUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(SpringBeanFactoryUtil.applicationContext == null) {
            SpringBeanFactoryUtil.applicationContext = applicationContext;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String name){
        return getApplicationContext().getBean(name);
    }

    public static <T> T getBean(Class<T> clazz){
        return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name,Class<T> clazz){
        return getApplicationContext().getBean(name, clazz);
    }
}

SpringBeanFactoryUtil只能获取我的自定义bean,不能获取HttpSession
我该怎么办?


问题答案:

如果我理解正确,则您想从范围更广(单个)的组件中访问会话范围中的某些内容,因此系统实际上无法知道您在该服务器中哪个潜在的并发会话被插入它会说在spring初始化时间未定义会话范围。

您可以使用ObjectFactory模式获得解决方案(可能的解决方案之一)

@Autowired
ObjectFactory<HttpSession> httpSessionFactory;

然后,在需要时,从绑定到会话的线程中:

HttpSession session = httpSessionFactory.getObject();

这样一来,spring绑定一条代码就可以在调用getObject()方法的类型上获取所需的对象,而不是尚不可用的实际对象。

请理解,如果在运行代码时没有会话绑定到当前线程,这将失败(返回null),因为没有会话可用。这意味着您要么从未能转发请求/会话的请求线程本地信息的线程中调用此代码,要么从没有意义的上下文中调用此代码。