先經過註解的javadoc,能夠了解到,@Scope在和@Component註解一塊兒修飾在類上,做爲類級別註解時,@Scope表示該類實例的範圍,在和@Bean一塊兒修飾在方法上,做爲方法級別註解時,@Scope表示該方法返回的實例的範圍。 對於@Scope註解,咱們經常使用的屬性通常就是:value和proxyMode,value就是指明使用哪一種做用域範圍,proxyMode指明使用哪一種做用域代理。
@Scope定義提供了的做用域範圍通常有:singleton單例、prototype原型、requestweb請求、sessionweb會話,同時咱們也能夠自定義做用域。html
若是指定爲proxyMode = ScopedProxyMode.TARGET_CLASS,那麼將使用cglib代理建立代理實例;若是指定爲proxyMode = ScopedProxyMode.INTERFACE,那麼將使用jdk代理建立代理實例;若是不指定,則直接在Spring容器啓動時建立該實例。並且使用代理建立代理實例時,只有在注入調用時,纔會真正建立類對象。
後面寫了一個例子實踐一下,自定義了一種同一分鐘的做用域範圍,即同一分鐘獲取的是相同實例。
首先自定義做用域範圍類TimeScope:java
/** * 首先自定義做用域範圍類TimeScope: * Scope接口提供了五個方法,只有get()和remove()是必須實現,get()中寫獲取邏輯, * 若是已有存儲中沒有該名稱的bean,則經過objectFactory.getObject()建立實例。 */ @Slf4j public class TimeScope implements Scope { private static Map<String, Map<Integer, Object>> scopeBeanMap = new HashMap<>(); @Override public Object get(String name, ObjectFactory<?> objectFactory) { Integer hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); // 當前是一天內的第多少分鐘 Integer minute = hour * 60 + Calendar.getInstance().get(Calendar.MINUTE); log.info("當前是第 {} 分鐘", minute); Map<Integer, Object> objectMap = scopeBeanMap.get(name); Object object = null; if (Objects.isNull(objectMap)) { objectMap = new HashMap<>(); object = objectFactory.getObject(); objectMap.put(minute, object); scopeBeanMap.put(name, objectMap); } else { object = objectMap.get(minute); if (Objects.isNull(object)) { object = objectFactory.getObject(); objectMap.put(minute, object); scopeBeanMap.put(name, objectMap); } } return object; } @Override public Object remove(String name) { return scopeBeanMap.remove(name); } @Override public void registerDestructionCallback(String name, Runnable callback) { } @Override public Object resolveContextualObject(String key) { return null; } @Override public String getConversationId() { return null; } }
/** * 而後註冊自定義的做用域範圍: */ @Configuration @Slf4j public class BeanScopeConfig { @Bean public CustomScopeConfigurer customScopeConfigurer() { CustomScopeConfigurer customScopeConfigurer = new CustomScopeConfigurer(); Map<String, Object> map = new HashMap<>(); map.put("timeScope", new TimeScope()); customScopeConfigurer.setScopes(map); return customScopeConfigurer; } @Bean @Scope(value = "timeScope", proxyMode = ScopedProxyMode.TARGET_CLASS) public TimeScopeBean timeScopeBean() { TimeScopeBean timeScopeBean = new TimeScopeBean(); timeScopeBean.setCurrentTime(System.currentTimeMillis()); log.info("time scope bean"); return timeScopeBean; } }
而後注入調用timeScopeBean,同一分鐘內重複調用,使用相同實例,不一樣分鐘將建立新實例
轉載自:秋月:https://www.wetsion.site/spring-boot-annotation-scope.htmlweb