001/* 002 * Copyright 2002-2012 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 org.apache.log4j.Logger#getLogger(String) 048 * @see java.util.logging.Logger#getLogger(String) 049 */ 050 public void setLoggerName(String loggerName) { 051 this.logger = LogFactory.getLog(loggerName); 052 } 053 054 055 @Override 056 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { 057 if (isLogEnabled()) { 058 String[] beanNames = beanFactory.getBeanDefinitionNames(); 059 for (String beanName : beanNames) { 060 String nameToLookup = beanName; 061 if (beanFactory.isFactoryBean(beanName)) { 062 nameToLookup = BeanFactory.FACTORY_BEAN_PREFIX + beanName; 063 } 064 Class<?> beanType = ClassUtils.getUserClass(beanFactory.getType(nameToLookup)); 065 if (beanType != null && beanType.isAnnotationPresent(Deprecated.class)) { 066 BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); 067 logDeprecatedBean(beanName, beanType, beanDefinition); 068 } 069 } 070 } 071 } 072 073 /** 074 * Logs a warning for a bean annotated with {@link Deprecated @Deprecated}. 075 * @param beanName the name of the deprecated bean 076 * @param beanType the user-specified type of the deprecated bean 077 * @param beanDefinition the definition of the deprecated bean 078 */ 079 protected void logDeprecatedBean(String beanName, Class<?> beanType, BeanDefinition beanDefinition) { 080 StringBuilder builder = new StringBuilder(); 081 builder.append(beanType); 082 builder.append(" ['"); 083 builder.append(beanName); 084 builder.append('\''); 085 String resourceDescription = beanDefinition.getResourceDescription(); 086 if (StringUtils.hasLength(resourceDescription)) { 087 builder.append(" in "); 088 builder.append(resourceDescription); 089 } 090 builder.append("] has been deprecated"); 091 writeToLog(builder.toString()); 092 } 093 094 /** 095 * Actually write to the underlying log. 096 * <p>The default implementations logs the message at "warn" level. 097 * @param message the message to write 098 */ 099 protected void writeToLog(String message) { 100 logger.warn(message); 101 } 102 103 /** 104 * Determine whether the {@link #logger} field is enabled. 105 * <p>Default is {@code true} when the "warn" level is enabled. 106 * Subclasses can override this to change the level under which logging occurs. 107 */ 108 protected boolean isLogEnabled() { 109 return logger.isWarnEnabled(); 110 } 111 112}