先经过注解的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