当前位置: 首页 > 知识库问答 >
问题:

Spring@Autowired-实例化新bean

沃瑾瑜
2023-03-14

需要一些关于Spring自动装配和范围的帮助。

这是基本的应用程序结构:

>

CustomHttpClient由我的应用程序中的多个服务使用。每当我使用CustomHttpClient时,我都会通过以下方式自动连接该客户端的实例:

@Autowired
private CustomHttpClient httpClient;

我使用拦截器修改CustomHttpClient中的一些变量,如下所示:

public class MyInterceptor extends HandlerInterceptorAdapter {
@Autowired CustomHttpClient httpClient;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
httpClient.setSomeProperty(newValue);
...

现在,问题来了。如果我按照上述方式设置了所有内容,那么每当我通过拦截器更改CustomHttpClient的任何设置时,只要VM正在运行,就会为所有其他客户端保留该新值。所以当我运行httpClient时。setSomeProperty()-该设置现在已永久保存。即使我从另一个客户端连接到应用程序

基本上,我需要有两样东西:

  1. 仍然能够通过拦截器(请求拦截器,通过配置)覆盖CustomHttpClient的默认设置
  2. 确保为每个请求创建一个CustomHttpClient的新实例(在拦截器执行其“魔法”之后)

我尝试将CustomHttpClient的范围更改为@Scope(“原型”),但这样我就不能再使用拦截器更改CustomHttpClient的设置。

共有3个答案

苏丰茂
2023-03-14

默认情况下,Spring容器中通过XML或注释支持声明的所有bean都是单例的。如果将范围设置为prototype的bean注入到一个单例中,例如控制器,那么它只会注入一次。有一种方法可以实现这一目标。这就是您应该如何将bean范围声明为原型的方式。这意味着每次从容器调用这个bean时,容器都会给您一个新实例。

<bean id="shoppingCart" class="example.ShoppingCart" scope="request">
     <aop:scoped-proxy />
</bean>
濮阳茂材
2023-03-14

如果拦截器只是添加一些属性,那么使用线程本地应该是更好的选择。您可以调用ThreadLocal。设置(自定义映射)并在运行线程所需的任何位置使用它,当程序将离开控制器时,可以调用ThreadLocal。取消设置,将清除存储的值。

这样您就不会每次都需要一个新的HttpcLient实例,每次都需要一个新的实例也会是一个严重的缺陷。您将能够在运行线程中的任何位置使用您的自定义映射。

聂迪
2023-03-14

默认情况下,当您使用Autowired时,Springbean的作用域是singleton。这意味着spring将在您使用Autowired时注入相同的单例对象。通过制作scope原型,您指示Spring为每个@Autowired注入创建新对象,因此在您的拦截器中,将有自己的HttpClient副本,并且看不到其他HttpClient对象。

所以更好的方法是使用单例作用域,使用请求属性或线程本地在请求线程中携带您的自定义属性。ie而不是在拦截器中修改HttpClient属性,只需设置一些请求属性或线程本地变量并在CustomHttpClient类方法中处理这些自定义设置。

 类似资料:
  • 问题内容: 我对Spring不太熟悉,并且遇到以下情况: 存储库类: 使用存储库类的类: 我知道,如果我用注释并与一起使用,则 可以解决。问题是我处于一种需要创建带有反射的新实例的情况下。因此永远不会解决,并且始终为null。 在这种情况下有没有办法使用? 更好地解释我的情况:我有一些实现。在我的应用程序的设置阶段,我将创建以下实现。基本上: 然后,我有了一个泛型,可以 使用 ,上面的内容和反射内

  • 这是给正儿八经的“Springers”们的问题... 我想使用MongoRepository。所以我去了Spring.io网站的MongoDB CRUD操作教程; 第一个问题是他们使用的是Spring Boot。第二个问题是他们在接口上使用。那个注释似乎可以创建一个对象(以后从这个对象调用方法...) 所以....我使用的是常规的spring MVC,而似乎在那里不起作用。 包含的类

  • 我的情况是: 我正在构建一个Spring Boot应用程序,当我在控制器中自动连接UserRepository时,它会初始化它,当我尝试调用findByUserName方法时,一切都正常。 用户控制器 创建控制器后,我需要使用Spring Security来保护控制器的路径,因此我在SecurityConfig类中添加了以下配置: 安全配置 现在,当我尝试将请求发布到/登录路径时,我在Custom

  • 作为大多数Spring Boot新用户,我对@Autow的问题:D 我已经在这里阅读了大量有关此注释的主题,但仍然无法找到解决问题的正确方法。 假设我们有这个Spring Boot层次结构: 类,我们希望在每次调用时实例化它: Out get controller,它会在每个请求中创建新的SomeRepo对象: 最后,使用@Autowired创建TestWire实例的类: 假设我们多次向“/”发出

  • JAR2(非Spring项目)

  • 问题内容: 无论如何,有没有指定实例化bean的顺序?即我想在其他bean之前实例化特定的bean,就像启动顺序一样。 我正在使用Spring 3.2和基于注释的声明方法。 问题答案: 如果豆 甲 取决于豆 乙 通过定义,或则的顺序被强制和由Spring容器固定。没问题 但是,如果要强制执行未通过显式依赖关系表示的特定的Bean创建顺序,请随时使用: 或更好(带有注释,也可以与Java配置一起使用