60 seconds to Spring (2)

该博客主要介绍Spring中Bean的部署模式,包括单例(Singleton)和非单例(Prototype)。单例模式下仅管理一个共享实例,原型模式每次请求都会创建新实例。还给出了演示两种模式差异的步骤,如创建CounterBean.java、在bean.xml中指定类、创建Main.java及使用ANT脚本构建执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

60 sec to Spring [TOC]

Bean Tutorial 2 - To Singleton or Not To Singleton

Beans are defined to be deployed in one of the two modes: Singleton and Non-Singleton (Prototype). When a bean is a singleton, only one shared instance of the bean will be managed. The prototype mode of a bean deployment results in the creation of a new bean instance every time a request for that specific bean is done. Tutorial 2 will demostrate the difference behaviour when defining a bean as Singleton and Prototype.

Note: By default all beans are deployed in singleton mode, unless you specify otherwise.

Step 1: Create a CounterBean.java in src

org/jarchitect/spring/tutorial2/CounterBean.java

package org.jarchitect.spring.tutorial2; public class CounterBean { private int counter; public CounterBean() { System.out.println("Construct CounterBean......"); } public int getCount() { return counter++; } } 

Step 2: Specify the CounterBean class in the bean.xml

Do notice that I have defined one CounterBean as singleton bean and the other as prototype bean.

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"  "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <description>jarchitect Spring Tutorial 2</description> <bean id="singletonBean" class="org.jarchitect.spring.tutorial2.CounterBean" singleton="true"/> <bean id="prototypeBean" class="org.jarchitect.spring.tutorial2.CounterBean" singleton="false"/> </beans>

Step 3: Create a Main.java in src

org/jarchitect/spring/tutorial2/Main.java

package org.jarchitect.spring.tutorial2; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import org.springframework.beans.factory.xml.XmlBeanFactory; public class Main { public static void main(String[] args) { try { //Read the configuration file InputStream is = new FileInputStream("bean.xml"); XmlBeanFactory factory = new XmlBeanFactory(is); //Instantiate an singleton object System.out.println("---- Singleton Bean ----"); CounterBean singletonBean = (CounterBean) factory.getBean("singletonBean"); System.out.println("First Call :- " + singletonBean.getCount()); singletonBean = (CounterBean) factory.getBean("singletonBean"); System.out.println("Second Call :- " + singletonBean.getCount()); System.out.println(""); //Instantiate an object System.out.println("---- Prototype Bean ----"); CounterBean prototypeBean = (CounterBean) factory.getBean("prototypeBean"); System.out.println("First Call :- " + prototypeBean.getCount()); prototypeBean = (CounterBean) factory.getBean("prototypeBean"); System.out.println("Second Call :- " + prototypeBean.getCount()); } catch (FileNotFoundException e) { e.printStackTrace(); } } }

Step 4: Use an ANT script to build and execute the Main class. Just run ant from the command prompt will do the trick.

Below are the output from ANT.

C:/60sec2Spring/SpringTutorial2>ant Buildfile: build.xml build: [javac] Compiling 2 source files to C:/60sec2Spring/SpringTutorial2/bin run: [java] Jun 1, 2004 12:16:42 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions [java] INFO: Loading XML bean definitions from (no description) [java] Jun 1, 2004 12:16:42 PM org.springframework.beans.factory.support.AbstractBeanFactory getBean [java] INFO: Creating shared instance of singleton bean 'singletonBean' [java] ---- Singleton Bean ---- [java] Construct CounterBean...... [java] First Call :- 0 [java] Second Call :- 1 [java] ---- Prototype Bean ---- [java] Construct CounterBean...... [java] First Call :- 0 [java] Construct CounterBean...... [java] Second Call :- 0 BUILD SUCCESSFUL Total time: 2 seconds

Done.

[TOC]

### Spring Integration with Redisson Distributed Lock Example Tutorial In applications requiring high availability and scalability, implementing distributed locks becomes essential when multiple instances need to coordinate access to shared resources. Integrating Spring with Redisson provides an effective solution for managing such locks. Redisson is a Java client for Redis that offers various features including distributed locks. To integrate Spring with Redisson for utilizing distributed locks: #### Configuration Setup Firstly, include necessary dependencies within `pom.xml` or build.gradle file depending on the project setup[^1]: For Maven projects: ```xml <dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>{latest_version}</version> </dependency> ``` Configure Redis connection properties in application.properties or application.yml files as follows[^2]: ```yaml spring.redis.host=localhost spring.redis.port=6379 ``` #### Implementing Distributed Locks Using Redisson To implement a simple method-level locking mechanism using Redisson's RLock interface: Create a utility class named `DistributedLocker.java`, which will handle acquiring and releasing locks around critical sections of code. ```java import org.redisson.api.RLock; import org.redisson.api.RedissonClient; public final class DistributedLocker { private static final int DEFAULT_LOCK_WAIT_TIME = 10; // seconds private static final int DEFAULT_LOCK_LEASE_TIME = 15; // seconds private final RedissonClient redissonClient; public DistributedLocker(RedissonClient redissonClient){ this.redissonClient = redissonClient; } /** * Acquires lock before executing given runnable task, * releases after completion regardless success/failure. */ public void executeWithLock(String lockName, Runnable action) { try{ RLock lock = redissonClient.getLock(lockName); boolean acquired = lock.tryLock(DEFAULT_LOCK_WAIT_TIME, DEFAULT_LOCK_LEASE_TIME, TimeUnit.SECONDS); if(acquired){ try{ action.run(); } finally { lock.unlock(); } }else{ throw new RuntimeException("Unable to acquire lock"); } } catch(InterruptedException e){ Thread.currentThread().interrupt(); throw new RuntimeException(e.getMessage(),e); } } } ``` Use this utility by injecting into services where synchronization across nodes matters most. For instance, consider updating inventory levels during order processing transactions without risking race conditions between concurrent requests hitting different server instances simultaneously[^3]. ```java @Service class OrderService { @Autowired private InventoryRepository repository; @Autowired private DistributedLocker locker; public void processOrder(OrderDetails details){ String productId = details.getProductId(); locker.executeWithLock(productId, ()->{ Optional<ProductInventory> maybeProduct = repository.findById(productId); ProductInventory product = maybeProduct.orElseThrow(() -> new ResourceNotFoundException("No matching products found")); updateStockLevel(product,details.getQuantity()); }); } } ``` This approach ensures only one thread can modify stock information at any point while others wait until released automatically once operations complete successfully or fail unexpectedly due to exceptions thrown inside locked blocks.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值