001/* 002 * Copyright 2002-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.context.annotation; 018 019import java.lang.annotation.Annotation; 020 021import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition; 022import org.springframework.beans.factory.config.BeanDefinition; 023import org.springframework.core.annotation.AnnotationAttributes; 024import org.springframework.util.Assert; 025 026/** 027 * A {@link ScopeMetadataResolver} implementation that by default checks for 028 * the presence of Spring's {@link Scope @Scope} annotation on the bean class. 029 * 030 * <p>The exact type of annotation that is checked for is configurable via 031 * {@link #setScopeAnnotationType(Class)}. 032 * 033 * @author Mark Fisher 034 * @author Juergen Hoeller 035 * @author Sam Brannen 036 * @since 2.5 037 * @see org.springframework.context.annotation.Scope 038 */ 039public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver { 040 041 private final ScopedProxyMode defaultProxyMode; 042 043 protected Class<? extends Annotation> scopeAnnotationType = Scope.class; 044 045 046 /** 047 * Construct a new {@code AnnotationScopeMetadataResolver}. 048 * @see #AnnotationScopeMetadataResolver(ScopedProxyMode) 049 * @see ScopedProxyMode#NO 050 */ 051 public AnnotationScopeMetadataResolver() { 052 this.defaultProxyMode = ScopedProxyMode.NO; 053 } 054 055 /** 056 * Construct a new {@code AnnotationScopeMetadataResolver} using the 057 * supplied default {@link ScopedProxyMode}. 058 * @param defaultProxyMode the default scoped-proxy mode 059 */ 060 public AnnotationScopeMetadataResolver(ScopedProxyMode defaultProxyMode) { 061 Assert.notNull(defaultProxyMode, "'defaultProxyMode' must not be null"); 062 this.defaultProxyMode = defaultProxyMode; 063 } 064 065 066 /** 067 * Set the type of annotation that is checked for by this 068 * {@code AnnotationScopeMetadataResolver}. 069 * @param scopeAnnotationType the target annotation type 070 */ 071 public void setScopeAnnotationType(Class<? extends Annotation> scopeAnnotationType) { 072 Assert.notNull(scopeAnnotationType, "'scopeAnnotationType' must not be null"); 073 this.scopeAnnotationType = scopeAnnotationType; 074 } 075 076 077 @Override 078 public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { 079 ScopeMetadata metadata = new ScopeMetadata(); 080 if (definition instanceof AnnotatedBeanDefinition) { 081 AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; 082 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor( 083 annDef.getMetadata(), this.scopeAnnotationType); 084 if (attributes != null) { 085 metadata.setScopeName(attributes.getString("value")); 086 ScopedProxyMode proxyMode = attributes.getEnum("proxyMode"); 087 if (proxyMode == ScopedProxyMode.DEFAULT) { 088 proxyMode = this.defaultProxyMode; 089 } 090 metadata.setScopedProxyMode(proxyMode); 091 } 092 } 093 return metadata; 094 } 095 096}