Spring的@Scope注解prototype

本文详细解释了Spring框架中如何在单例组件中注入非单例的原型bean,并介绍了ScopedProxyMode的不同设置,如TARGET_CLASS和INTERFACES,以及它们如何影响对象实例化和代理行为。
摘要由CSDN通过智能技术生成

spring IOC默认的组件都是单例,那对于非单例的组件,需要通过注解:

@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)

那么当一个单例组件A,注入了非单例的组件B:

@Component
class A {
  @Autowride
  private B b;
  
  public void  printB() {
     System.out.println(b.toString());
  }
}
@Compnent
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
class B {
}

因为A是单例,所以注入的属性B相当于也是单例了。即:A中的B是固定不变的了,每次调用a.printB,输出b都是一样的。那么如果想要每次调用a.printB,输出b都不一样,就需要使用代理proxyMode

@Compnent
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
class B {
}

这样每次调用b.toString()的时候就会通过代理new一个b。这个文章解释的很好:

Spring - @Scope and scoped-proxy class based Example​www.logicbig.com/tutorials/spring-framework/spring-core/scoped-proxy.html​编辑

This is another way to inject a short-lived scoped bean into long-lived scoped bean. For example injecting a prototype bean into a singleton bean.

We need to inject a proxy object that exposes the same public interface as the original scoped object.

Spring uses CGLIB to create the proxy object.

The proxy object delegates method calls to the real object.

Each access of underlying prototype object causes a new object to be created.

Example

Prototype bean

package com.logicbig.example;

import java.time.LocalDateTime;

public class MyPrototypeBean {

  private String dateTimeString = LocalDateTime.now().toString();

  public String getDateTime() {
      return dateTimeString;
  }
}

Singleton bean

package com.logicbig.example;

import org.springframework.beans.factory.annotation.Autowired;

public class MySingletonBean {

  @Autowired
  private MyPrototypeBean prototypeBean;

  public void showMessage(){
      System.out.println("Hi, the time is "+prototypeBean.getDateTime());
  }
}

Main class Configuring the Scoped Proxy for Prototype bean

package com.logicbig.example;

import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.*;

@Configuration
public class AppConfig {

  @Bean
  @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,
                      proxyMode = ScopedProxyMode.TARGET_CLASS)
  public MyPrototypeBean prototypeBean () {
      return new MyPrototypeBean();
  }

  @Bean
  public MySingletonBean singletonBean () {
      return new MySingletonBean();
  }

  public static void main (String[] args) throws InterruptedException {
      AnnotationConfigApplicationContext context =
                          new AnnotationConfigApplicationContext(AppConfig.class);
      MySingletonBean bean = context.getBean(MySingletonBean.class);
      bean.showMessage();
      Thread.sleep(1000);

      bean.showMessage();
  }
}

Output

Hi, the time is 2021-05-05T02:03:45.349
Hi, the time is 2021-05-05T02:03:46.372

In above example proxyMode=ScopedProxyMode.TARGET_CLASS causes an AOP proxy to be injected at the target injection point. The default proxyMode is ScopedProxyMode.NO.

Another possible value, ScopedProxyMode.INTERFACES creates JDK dynamic proxy (instead of class based CGLIB proxy) which can only take the target bean's interface types.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值