• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
你的小铃铛呀
博客园    首页    新随笔    联系   管理    订阅  订阅

spring中的bean对象的有关了解

@Configuration
public class AppConfig {
  
  @Bean
  public MyBean getMyBean() {
    MyBean myBean = new MyBean();
    myBean.setName("Example");
    return myBean;
  }
  
  // 其他的@Bean方法...
}

上述是一个配置类,里面有个@Bean注解修饰,@Configuration注解的类里面的方法在Spring容器启动时并不会立即执行,而是在需要获取被@Bean注解标记的Bean实例时才会被调用。这样可以实现懒加载,只有在需要使用某个Bean时才去创建它。

如何获取到这个类呢

 第一种:
@Autowired
private MyBean myBean;
第二种:
@Autowired
private ApplicationContext applicationContext;
public void someMethod() {
AppConfig appConfig= applicationContext.getBean(AppConfig.class);
MyBean myBean = appConfig.getMyBean();
// 使用获得的 MyBean 对象
}

需要注意的是默认情况下会注入同一个对象实例。这是因为被 @Bean 注解标记的方法的返回值默认是单例的,也就是说在整个应用程序的生命周期中,都会共享同一个对象实例。不管在哪个类里面调用,也都是同一个对象,

如果在任何地方重新对该对象 进行赋值,那么所有使用到这个对象的地方都会受到影响,因为它们引用的都是同一个对象实例

问题来了,当时多线程的时候,就会出现线程安全问题,对于这种线程安全问题,可以采取以下几种策略

 

  1. 使用同步机制:通过在关键代码块或方法上添加synchronized关键字,确保同一时间只有一个线程可以进入该代码块或方法
    public class ThreadSafeBean {
        private int count;
    
        public synchronized void increment() {
            count++;
        }
    
        public synchronized int getCount() {
            return count;
        }
    }

    在上面的示例中,通过使用synchronized关键字修饰increment()和getCount()方法,确保在多线程环境下对count属性的访问和操作是线程安全的

  2. 使用线程安全的数据结构:使用线程安全的数据结构,如java.util.concurrent.atomic包下的原子类,可以避免使用同步机制来实现线程安全。

 

public class ThreadSafeBean {
    private AtomicInteger count = new AtomicInteger(0);

    public void increment() {
        count.incrementAndGet();
    }

    public int getCount() {
        return count.get();
    }
}

在上面的示例中,使用AtomicInteger类来替代普通的int类型,它提供了原子性操作,避免了使用synchronized关键字来实现线程安全。

  1. 使用线程安全的容器:使用线程安全的容器来存储和访问Bean实例,确保多线程环境下的访问操作是线程安全的。
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.ConcurrentHashMap;
    
    @Component
    public class ThreadSafeBeanContainer {
        private ConcurrentHashMap<String, ThreadSafeBean> beanMap;
    
        @Autowired
        public ThreadSafeBeanContainer() {
            beanMap = new ConcurrentHashMap<>();
        }
    
        public void addBean(String name, ThreadSafeBean bean) {
            beanMap.put(name, bean);
        }
    
        public ThreadSafeBean getBean(String name) {
            return beanMap.get(name);
        }
    }

    在上面的示例中,使用ConcurrentHashMap作为线程安全的容器来存储ThreadSafeBean实例,并提供线程安全的访问方法。

  2. 使用线程安全的注解:Spring提供了一些线程安全的注解,例如@Scope("prototype")将bean的作用域设置为原型模式,每次请求都会创建一个新的实例,从而避免线程安全问题。
    @Component
    @Scope("prototype")
    public class UserService {
        private int count = 0;
    
        public void addUser() {
            count++;
        }
    
        public int getUserCount() {
            return count;
        }
    }

     

 

posted @ 2023-07-17 15:55  你的小铃铛呀  阅读(36)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3