001/* 002 * Copyright 2012-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 * http://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.boot.diagnostics.analyzer; 018 019import java.io.PrintWriter; 020import java.io.StringWriter; 021import java.lang.reflect.Proxy; 022 023import org.springframework.beans.factory.BeanNotOfRequiredTypeException; 024import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; 025import org.springframework.boot.diagnostics.FailureAnalysis; 026 027/** 028 * An {@link AbstractFailureAnalyzer} that performs analysis of failures caused by a 029 * {@link BeanNotOfRequiredTypeException}. 030 * 031 * @author Andy Wilkinson 032 */ 033public class BeanNotOfRequiredTypeFailureAnalyzer 034 extends AbstractFailureAnalyzer<BeanNotOfRequiredTypeException> { 035 036 private static final String ACTION = "Consider injecting the bean as one of its " 037 + "interfaces or forcing the use of CGLib-based " 038 + "proxies by setting proxyTargetClass=true on @EnableAsync and/or " 039 + "@EnableCaching."; 040 041 @Override 042 protected FailureAnalysis analyze(Throwable rootFailure, 043 BeanNotOfRequiredTypeException cause) { 044 if (!Proxy.isProxyClass(cause.getActualType())) { 045 return null; 046 } 047 return new FailureAnalysis(getDescription(cause), ACTION, cause); 048 } 049 050 private String getDescription(BeanNotOfRequiredTypeException ex) { 051 StringWriter description = new StringWriter(); 052 PrintWriter printer = new PrintWriter(description); 053 printer.printf( 054 "The bean '%s' could not be injected as a '%s' because it is a " 055 + "JDK dynamic proxy that implements:%n", 056 ex.getBeanName(), ex.getRequiredType().getName()); 057 for (Class<?> requiredTypeInterface : ex.getRequiredType().getInterfaces()) { 058 printer.println("\t" + requiredTypeInterface.getName()); 059 } 060 return description.toString(); 061 } 062 063}