首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从Spring Boot中的公共类获取会话?

如何从Spring Boot中的公共类获取会话?
EN

Stack Overflow用户
提问于 2018-01-29 00:43:26
回答 3查看 10.8K关注 0票数 8

我想从一个普通的类中获取会话。使用@Autowired不起作用。

代码语言:javascript
复制
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
    }
}

构造函数也不起作用

代码语言:javascript
复制
@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,它也不起作用。

代码语言:javascript
复制
@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

我该怎么办?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-01-29 01:29:35

如果我没理解错的话,你想从一个更大范围(单例)的组件中访问会话作用域中的某些东西,这样系统就不能知道你在服务器中的哪个潜在并发会话中感兴趣,实际上在spring初始化时它会说会话作用域还没有定义。

您可以使用ObjectFactory模式来解决这个问题(可能的解决方案中的1个)

代码语言:javascript
复制
import `org.springframework.beans.factory.ObjectFactory`;
// ...
// ...

@Autowired
ObjectFactory<HttpSession> httpSessionFactory;

然后,当您需要它时,从绑定到会话的线程:

代码语言:javascript
复制
HttpSession session = httpSessionFactory.getObject();

通过这种方式,spring绑定一个接收器,以获取您调用getObject()方法时所需的类型的对象,而不是尚未提供的实际对象。

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

票数 9
EN

Stack Overflow用户

发布于 2019-09-23 19:27:45

创建pojo风格的会话作用域bean。注入它,并在需要设置或从HttpSession获取数据的地方使用。Spring会自动将相应的数据设置到HttpSession中。例如:

代码语言:javascript
复制
@Component
@Scope(proxyMode= ScopedProxyMode.TARGET_CLASS, value=WebApplicationContext.SCOPE_SESSION)
public class SessionData {
    private Currency currency;

    public Currency getCurrency() {
        return currency;
    }

    public void setCurrency(Currency currency) {
        this.currency = currency;
    }
}


@Service
public class UserService {

   @Autowired
   private SessionData sessionData;

   public Currency getCurrentCurrency() {
       return sessionData.getCurrency();
   }

   public void setCurrentCurrency(Currency currency) {
       sessionData.setCurrency(currency);
   }
}

这样,使用UserService获取/设置当前货币将反映在当前HttpSession中,并具有相应的会话bean属性的属性名称(' currency ')。

票数 1
EN

Stack Overflow用户

发布于 2020-01-03 22:45:41

单例类中的@Autowired HttpSession session将注入一个AutowireUtils$ObjectFactoryDelegatingInvocationHandler - Spring似乎足够聪明,可以自动为范围较窄的对象创建代理。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48488735

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档