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.beans.factory.config; 018 019import org.apache.commons.logging.Log; 020import org.apache.commons.logging.LogFactory; 021 022import org.springframework.beans.BeansException; 023import org.springframework.beans.factory.BeanFactory; 024import org.springframework.util.ClassUtils; 025import org.springframework.util.StringUtils; 026 027/** 028 * Bean factory post processor that logs a warning for {@link Deprecated @Deprecated} beans. 029 * 030 * @author Arjen Poutsma 031 * @since 3.0.3 032 */ 033public class DeprecatedBeanWarner implements BeanFactoryPostProcessor { 034 035 /** 036 * Logger available to subclasses. 037 */ 038 protected transient Log logger = LogFactory.getLog(getClass()); 039 040 /** 041 * Set the name of the logger to use. 042 * The name will be passed to the underlying logger implementation through Commons Logging, 043 * getting interpreted as log category according to the logger's configuration. 044 * <p>This can be specified to not log into the category of this warner class but rather 045 * into a specific named category. 046 * @see org.apache.commons.logging.LogFactory#getLog(String) 047 * @see java.util.logging.Logger#getLogger(String) 048 */ 049 public void setLoggerName(String loggerName) { 050 this.logger = LogFactory.getLog(loggerName); 051 } 052 053 054 @Override 055 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 056 if (isLogEnabled()) { 057 String[] beanNames = beanFactory.getBeanDefinitionNames(); 058 for (String beanName : beanNames) { 059 String nameToLookup = beanName; 060 if (beanFactory.isFactoryBean(beanName)) { 061 nameToLookup = BeanFactory.FACTORY_BEAN_PREFIX + beanName; 062 } 063 Class<?> beanType = beanFactory.getType(nameToLookup); 064 if (beanType != null) { 065 Class<?> userClass = ClassUtils.getUserClass(beanType); 066 if (userClass.isAnnotationPresent(Deprecated.class)) { 067 BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); 068 logDeprecatedBean(beanName, beanType, beanDefinition); 069 } 070 } 071 } 072 } 073 } 074 075 /** 076 * Logs a warning for a bean annotated with {@link Deprecated @Deprecated}. 077 * @param beanName the name of the deprecated bean 078 * @param beanType the user-specified type of the deprecated bean 079 * @param beanDefinition the definition of the deprecated bean 080 */ 081 protected void logDeprecatedBean(String beanName, Class<?> beanType, BeanDefinition beanDefinition) { 082 StringBuilder builder = new StringBuilder(); 083 builder.append(beanType); 084 builder.append(" ['"); 085 builder.append(beanName); 086 builder.append('\''); 087 String resourceDescription = beanDefinition.getResourceDescription(); 088 if (StringUtils.hasLength(resourceDescription)) { 089 builder.append(" in "); 090 builder.append(resourceDescription); 091 } 092 builder.append("] has been deprecated"); 093 writeToLog(builder.toString()); 094 } 095 096 /** 097 * Actually write to the underlying log. 098 * <p>The default implementations logs the message at "warn" level. 099 * @param message the message to write 100 */ 101 protected void writeToLog(String message) { 102 logger.warn(message); 103 } 104 105 /** 106 * Determine whether the {@link #logger} field is enabled. 107 * <p>Default is {@code true} when the "warn" level is enabled. 108 * Subclasses can override this to change the level under which logging occurs. 109 */ 110 protected boolean isLogEnabled() { 111 return logger.isWarnEnabled(); 112 } 113 114}